Khi nào bạn sẽ sử dụng các chiến lược hợp nhất git khác nhau?


429

Từ trang man trên git-merge, có một số chiến lược hợp nhất bạn có thể sử dụng.

  • giải quyết - Điều này chỉ có thể giải quyết hai đầu (tức là nhánh hiện tại và nhánh khác mà bạn đã kéo từ đó) bằng thuật toán hợp nhất 3 chiều. Nó cố gắng cẩn thận phát hiện sự mơ hồ hợp nhất chéo và được coi là nói chung an toàn và nhanh chóng.

  • đệ quy - Điều này chỉ có thể giải quyết hai đầu bằng thuật toán hợp nhất 3 chiều. Khi có nhiều hơn một tổ tiên chung có thể được sử dụng để hợp nhất 3 chiều, nó sẽ tạo ra một cây hợp nhất của tổ tiên chung và sử dụng đó làm cây tham chiếu cho hợp nhất 3 chiều. Điều này đã được báo cáo dẫn đến ít xung đột hợp nhất hơn mà không gây ra sự hợp nhất sai bởi các thử nghiệm được thực hiện trên các cam kết hợp nhất thực tế được lấy từ lịch sử phát triển nhân Linux 2.6. Ngoài ra, điều này có thể phát hiện và xử lý các hợp nhất liên quan đến đổi tên. Đây là chiến lược hợp nhất mặc định khi kéo hoặc sáp nhập một nhánh.

  • bạch tuộc - Điều này giải quyết nhiều hơn trường hợp hai đầu, nhưng từ chối thực hiện hợp nhất phức tạp cần giải quyết thủ công. Nó chủ yếu có nghĩa là được sử dụng để bó các đầu chi nhánh chủ đề lại với nhau. Đây là chiến lược hợp nhất mặc định khi kéo hoặc hợp nhất nhiều chi nhánh.

  • của chúng tôi - Điều này giải quyết bất kỳ số lượng đầu, nhưng kết quả của sự hợp nhất luôn luôn là đầu chi nhánh hiện tại. Nó có nghĩa là được sử dụng để thay thế lịch sử phát triển cũ của các nhánh bên.

  • cây con - Đây là một chiến lược đệ quy sửa đổi. Khi hợp nhất cây A và B, nếu B tương ứng với cây con của A, B trước tiên được điều chỉnh để phù hợp với cấu trúc cây của A, thay vì đọc các cây ở cùng cấp độ. Điều chỉnh này cũng được thực hiện cho cây tổ tiên chung.

Khi nào tôi nên chỉ định một cái gì đó khác với mặc định? Những kịch bản nào là tốt nhất cho?

Câu trả lời:


305

Tôi không quen với việc giải quyết, nhưng tôi đã sử dụng những người khác:

Đệ quy

Đệ quy là mặc định cho các hợp nhất không chuyển tiếp nhanh. Chúng ta đều quen thuộc với điều đó.

Bạch tuộc

Tôi đã sử dụng bạch tuộc khi tôi có một số cây cần được sáp nhập. Bạn thấy điều này trong các dự án lớn hơn, nơi nhiều chi nhánh đã có sự phát triển độc lập và tất cả đã sẵn sàng để cùng nhau thành một đầu.

Một nhánh bạch tuộc hợp nhất nhiều đầu trong một lần cam kết miễn là nó có thể làm điều đó một cách sạch sẽ.

Để minh họa, hãy tưởng tượng bạn có một dự án có một chủ, và sau đó ba nhánh để hợp nhất (gọi chúng là a, b và c).

Một loạt các sự hợp nhất đệ quy sẽ trông như thế này (lưu ý rằng sự hợp nhất đầu tiên là một sự chuyển tiếp nhanh, vì tôi đã không ép buộc đệ quy):

hàng loạt các hợp nhất đệ quy

Tuy nhiên, một sự hợp nhất bạch tuộc sẽ trông như thế này:

commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...

bạch tuộc hợp nhất

Của chúng tôi

Của chúng tôi == Tôi muốn kéo vào một cái đầu khác, nhưng vứt bỏ tất cả những thay đổi mà người đứng đầu giới thiệu.

Điều này giữ cho lịch sử của một chi nhánh mà không có bất kỳ tác động của chi nhánh.

(Đọc: Nó thậm chí không xem xét các thay đổi giữa các nhánh đó. Các nhánh chỉ được hợp nhất và không có gì được thực hiện cho các tệp. Nếu bạn muốn hợp nhất trong nhánh khác và mỗi khi có câu hỏi "phiên bản tệp của chúng tôi hoặc của chúng phiên bản "bạn có thể sử dụng git merge -X ours)

Subtree

Subtree rất hữu ích khi bạn muốn hợp nhất trong một dự án khác vào một thư mục con của dự án hiện tại của bạn. Hữu ích khi bạn có một thư viện mà bạn không muốn đưa vào như một mô hình con.


1
Vậy lợi thế thực sự duy nhất của Ocotopus là giảm số lượng cam kết hợp nhất trong cây?
Otto

60
Bạn không cần chỉ định chiến lược hợp nhất bạch tuộc : nó được sử dụng tự động nếu bạn hợp nhất nhiều hơn hai nhánh ( git merge A B ...).
Jakub Narębski

Xin lỗi vì đã lạc đề, nhưng công cụ mà bạn đã tạo ra những ảnh chụp màn hình đó là gì? Nó trông giống như một hình ảnh thực sự tuyệt vời / khá đẹp về lịch sử chi nhánh ...
Bernd Haug

4
gitg cho những người trên môi trường linux.
Akash Agrawal

2
Gợi ý -X oursnày là tuyệt vời, chỉ giúp tôi tiết kiệm một giờ làm việc.
Michael

49

Trên thực tế, hai chiến lược duy nhất bạn muốn chọn là của chúng tôi nếu bạn muốn từ bỏ các thay đổi do chi nhánh mang lại, nhưng giữ chi nhánh trong lịch sử và phụ thuộc nếu bạn hợp nhất dự án độc lập vào thư mục con của siêu dự án (như 'git-gui' trong ' kho git ').

hợp nhất bạch tuộc được sử dụng tự động khi hợp nhất nhiều hơn hai nhánh. giải quyết ở đây chủ yếu là vì lý do lịch sử, và khi bạn bị ảnh hưởng bởi các trường hợp góc chiến lược hợp nhất đệ quy .


Tôi đã phải chọn 'giải quyết' thay vì 'đệ quy' mặc định cho hợp nhất hai đầu có lỗi git-write-tree gây tử vong. Chiến lược 'Giải quyết' được hợp nhất sạch sẽ. Nó có thể phải làm với việc di chuyển rất nhiều tệp trong nhánh được hợp nhất.
thaddeusmt

@thaddeusmt: Thú vị. Bạn có thể vui lòng, nếu có thể, gửi báo cáo lỗi về thất bại của chiến lược hợp nhất "đệ quy" này vào danh sách gửi thư không? Cảm ơn trước.
Jakub Narębski

@ JakubNarębski Tôi không chắc chắn làm thế nào tôi có đủ thông tin để gửi báo cáo lỗi có ý nghĩa, tôi là một n00b với Git, xin lỗi. Như tôi đã đề cập trong câu trả lời của mình ở đây ( stackoverflow.com/a/10636464/164439 ) tôi đoán là điều đó phải làm với tôi để nhân đôi các thay đổi trong cả hai nhánh và "giải quyết" thực hiện tốt hơn việc bỏ qua các thay đổi trùng lặp.
thaddeusmt

@ JakubNarębski bởi bây giờ bạn cũng có thể chọn họ , mà là theo hướng dẫn "đối lập với chúng ta . Của họ không phải là lựa chọn tự động cho bạn Có thể bạn hơi có thể cập nhật anwser của bạn, thêm. Họ lựa chọn
SebNag

3
@SebTu: không có theirschiến lược hợp nhất (nghĩa là --strategy=theirs), nhưng có theirstùy chọn cho recursivechiến lược hợp nhất mặc định (nghĩa là --strategy=recursive --strategy-option=theirs, hoặc chỉ -Xtheirs).
Jakub Narębski

23

Chiến lược hợp nhất "Giải quyết" và "Đệ quy"

Đệ quy là chiến lược hai đầu mặc định hiện tại, nhưng sau khi tìm kiếm, cuối cùng tôi đã tìm thấy một số thông tin về chiến lược hợp nhất "giải quyết".

Lấy từ cuốn sách O'Reilly Kiểm soát phiên bản với Git ( Amazon ) (diễn giải):

Ban đầu, "giải quyết" là chiến lược mặc định cho việc sáp nhập Git.

Trong các tình huống hợp nhất chéo, khi có nhiều hơn một cơ sở hợp nhất có thể, chiến lược giải quyết hoạt động như thế này: chọn một trong những cơ sở hợp nhất có thể và hy vọng điều tốt nhất. Điều này thực sự không tệ như âm thanh. Nó thường chỉ ra rằng người dùng đã làm việc trên các phần khác nhau của mã. Trong trường hợp đó, Git phát hiện ra rằng nó đang kết hợp lại một số thay đổi đã có và bỏ qua các thay đổi trùng lặp, tránh xung đột. Hoặc, nếu đây là những thay đổi nhỏ gây ra xung đột, ít nhất là xung đột sẽ dễ dàng cho nhà phát triển xử lý ..

Tôi đã hợp nhất thành công các cây bằng cách sử dụng "giải quyết" thất bại với chiến lược đệ quy mặc định. Tôi đã nhận được fatal: git write-tree failed to write a treelỗi, và nhờ bài đăng trên blog này ( gương ) tôi đã thử "giải quyết", nó đã hoạt động. Tôi vẫn không chắc chắn chính xác tại sao ... nhưng tôi nghĩ rằng đó là do tôi đã thay đổi trùng lặp ở cả hai cây và giải quyết "bỏ qua" chúng đúng cách.


Tôi đang sử dụng hợp nhất 3 chiều (p4merge) và tôi đã có xung đột được ghi vào tệp .BASE khi hợp nhất đệ quy không thành công. Rơi lại để giải quyết - chiến lược đã giúp trong trường hợp này.
mrzl


-2

Như các câu trả lời ở trên không hiển thị tất cả các chi tiết chiến lược. Ví dụ, một số câu trả lời là mất tích các chi tiết về việc nhập khẩu resolvetùy chọn và recursivecó nhiều lựa chọn phụ như ours, theirs, patience, renormalizevv

Do đó, tôi khuyên bạn nên truy cập gittài liệu chính thức giải thích tất cả các tính năng có thể có:

https://git-scm.com/docs/merge-str Strategies

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.