không có cách nào để thêm một cam kết một chi nhánh xen kẽ với git commit. Có nhiều cách để sử dụng lệnh “đường ống dẫn nước” ở mức độ thấp để thực hiện chính xác những gì bạn mô tả, nhưng giao diện được hình thành bởi các lệnh này không được thiết kế để sử dụng tương tác . Có những cách chắc chắn để làm những gì bạn muốn; tùy thuộc vào các chi tiết của những thay đổi của bạn và nội dung của các chi nhánh liên quan đến nó có thể khá đơn giản.
The Easy điển hình: Chỉ cần sử dụng git checkout
Khi chuyển ngành, git checkout mà vẫn duy trì những thay đổi không bị giam hoặc từ chối chuyển đổi (trừ khi bạn sử dụng --force
, --merge
, hoặc --conflict
). Vì vậy, miễn là các thay đổi không được cam kết của bạn chỉ chạm vào các tệp giống nhau ở cả HEAD (nhánh hiện tại) và nhánh đích của bạn, git checkout sẽ để lại những thay đổi đó trong chỉ mục và/hoặc cây đang hoạt động trong khi chuyển đổi nhánh. Nếu thay đổi không bị giam của bạn đáp ứng điều kiện này thì bạn có thể làm điều này:
git checkout safe-branch
git add -- files-with-safe-changes
git commit
git checkout -
Bạn cũng có thể sử dụng git add --patch
đến giai đoạn và chỉ cam kết một số thay đổi trong các tập tin.
Sau đó, "thay đổi an toàn" của bạn sẽ là một phần của "an toàn"; chuyển về chi nhánh ban đầu của bạn sẽ "bỏ chúng lại" (hãy nhớ rằng, git checkout chỉ giữ lại các thay đổi không được cam kết khi chuyển nhánh).
Nếu các thay đổi khác của bạn phụ thuộc vào “thay đổi an toàn”, bạn có thể cần phải hợp nhất “nhánh an toàn” vào nhánh đang hoạt động của bạn (hoặc tùy thuộc vào quy trình làm việc của bạn). '). Để thực hiện điều này, bạn sẽ phải giấu các thay đổi không được cam kết của bạn (vì cả việc hợp nhất và rebase sẽ từ chối hoạt động nếu có những thay đổi không được cam kết).
git stash save
git merge safe-branch
git stash pop --index
Nếu những thay đổi khác của bạn không phụ thuộc vào sự “thay đổi an toàn”, sau đó bạn có lẽ không nên bận tâm với một hợp nhất hoặc rebase. Cuối cùng, bạn sẽ hợp nhất các chi nhánh này lại với nhau (ví dụ: bằng cách hợp nhất chúng thành một nhánh ‘qa’ để thử nghiệm trước khi phát hành), nhưng không có lý do gì để hợp nhất chúng sớm.
Tuy nhiên dễ dàng, nhưng một chút mạo hiểm: git checkout -m
Nếu là người đầu tiên git checkout phàn nàn “Bạn phải thay đổi địa phương để some‑file
; không chuyển đổi chi nhánh. ”, điều đó có nghĩa là bạn có các thay đổi chưa được sửa đổi đối với some-file
và tệp khác với các mẹo của‘ chi nhánh an toàn ’và chi nhánh hiện tại của bạn; bạn sẽ cần một cách tiếp cận khác.
Nếu bạn tự tin rằng những thay đổi sẽ được áp dụng sạch lên phiên bản của some‑file
đó là trong 'an toàn ngành', sau đó bạn có thể sử dụng tùy chọn -m
/--merge
nói git checkout để cố gắng thích nghi với những thay đổi để chúng áp dụng cho các tệp trong 'an toàn' chi nhánh '. Nếu hợp nhất không thể được thực hiện một cách sạch sẽ, thì bạn sẽ kết thúc với một cuộc xung đột hợp nhất và có thể khó khôi phục các thay đổi ban đầu của bạn (đây là lý do tại sao tôi gọi nó là "nguy hiểm").
an toàn: git stash
+ git checkout -m
Vì bạn thực sự chỉ muốn di chuyển một tập hợp con của những thay đổi trở lại ‘an toàn ngành’, nó có thể là tốt hơn để tập trung vào chỉ những thay đổi đó. Một phương pháp là sử dụng git stash để tạm thời lưu các thay đổi hiện tại của bạn để bạn không phải kéo tất cả chúng trở lại 'an toàn' chi nhánh '(và sau đó kéo một số/hầu hết trong số chúng trở lại nhánh đang hoạt động của bạn).
git stash save
git checkout stash -- files-with-save-changes
git checkout -m safe-branch
git commit
git checkout -
git stash pop --index
Các biến thể khác có thể thực hiện được. Bạn có thể sử dụng git checkout -p stash -- files
để chỉ chọn một số thay đổi trong các tệp đó. Nếu không có thay đổi theo từng giai đoạn, thì trước tiên bạn có thể đặt “thay đổi an toàn”, git add -- files
(một lần nữa, tùy chọn với -p
), sử dụng git stash save --keep-index
, chuyển đổi nhánh (có hợp nhất) và sau đó cam kết (tức là thay thế git checkout stash -- files
bằng tiền -ảnh báo “thay đổi an toàn” và git stash --keep-index
).
Trong tình huống này, tôi xem xét git checkout -m
để được an toàn vì chúng tôi sử dụng git stash để duy trì một bản sao của những thay đổi hiện hành; nếu nỗ lực kết hợp ba chiều dẫn đến lộn xộn vô vọng, thì bạn có thể dễ dàng từ bỏ ý tưởng đưa "thay đổi an toàn" vào 'an toàn' chi nhánh 'và trở lại làm việc: chuyển về nhánh ban đầu và bật stash (git checkout -f - && git stash pop
).
Một lần nữa, nếu các thay đổi khác của bạn phụ thuộc vào "thay đổi an toàn" thì bạn sẽ cần hợp nhất hoặc rebase. Bạn cũng có thể làm điều này trước khi popping stash (vì bạn cần một chỉ số rõ ràng và cây làm việc để làm việc hợp nhất/rebase).
Nếu bạn sẽ không hợp nhất nhánh làm việc của bạn với (hoặc rebase nó lên) ngay lập tức 'an toàn' chi nhánh, sau đó bạn có thể muốn hoàn tác "thay đổi an toàn" sau khi bạn bật stash (" thay đổi an toàn ”đã được lưu trong stash gốc và có thể bạn không muốn kết thúc bằng các cam kết thực hiện các thay đổi tương tự từ đầu trong hai chi nhánh khác nhau). Một khi bạn đã bật stash, sử dụng git checkout -- files-with-safe-changes
để hoàn nguyên các tệp đó về phiên bản ở đầu nhánh đang hoạt động.
Các “hệ thống ống nước” giao diện được thiết kế để sử dụng trong kịch bản. Nó sẽ là cồng kềnh để sử dụng chúng trực tiếp trên dòng lệnh. Các phiên bản đầu tiên của git commit (và hầu hết các lệnh Git khác) là các kịch bản lệnh shell dựa trên giao diện này. Chúng vẫn có thể được viết như các kịch bản shell ngày nay, nhưng các phiên bản C thường nhanh hơn nhiều. Các bước cần thiết để cam kết với chi nhánh thay thế là:
thiết lập chỉ mục thay thế dựa trên cây ở đầu “nhánh an toàn”,
cập nhật chỉ mục với thay đổi “an toàn” (nếu thay đổi có thể không được áp dụng sạch sẽ? nó là tốt đẹp để có một cây làm việc để cho người dùng giải quyết các xung đột),
viết chỉ mục ra làm đối tượng cây,
tạo đối tượng cam kết mới trỏ đến cây mới và có mẹo hiện tại của “chi nhánh an toàn” với tư cách là phụ huynh của nó,
cập nhật "nhánh an toàn" để trỏ đến cam kết mới.
Không có gì về mặt kỹ thuật sai với cam kết của bạn “thay đổi an toàn” trong hai chi nhánh, nhưng nó thường là một ý tưởng tốt để đảm bảo mỗi thay đổi bắt nguồn từ chỉ một nơi duy nhất.
Vì thanh toán không chạm vào các tệp đã sửa đổi, sẽ không thể chỉ là 'checkout master; thêm một; cam kết; thanh toán exp' và tiếp tục? Giả sử rằng các thay đổi không được tổ chức. – rlduffy
@rlduffy: nó sẽ hoạt động. Tôi luôn có xu hướng cẩn thận hơn với các thiết bị chuyển mạch nhánh. – VonC
Nếu ‘exp’ cam kết vượt quá ‘safe’ (tôi không thể quyết định điều này từ mô tả của OP) thì bạn sẽ không muốn 'git checkout safe && git merge exp' vì nó sẽ kéo theo các cam kết khác. Nếu bạn chỉ muốn cắt giảm ‘a’ của ‘exp’, thì tôi sẽ chỉ chọn món anh ta vào 'an toàn' thay vì sáp nhập nó. –