Git: Tìm tổ tiên chung gần đây nhất của hai nhánh


844

Làm thế nào để tìm ra tổ tiên chung gần đây nhất của hai nhánh Git?


3
Xác định gần đây nhất: thời gian thực, số lần xác nhận, số liệu khác?
Ciro Santilli 冠状 病毒 审查 事件

2
Có liên quan (hợp nhất chéo chéo): stackoverflow.com/questions/26370185/
Giả

1
@CiroSantilli 改造 心 心 996ICU nó giống nhau trong bất kỳ số liệu nào, phải không?
YakovL

@YakovL Tôi tin là không vì phân nhánh và vì bạn có thể đặt ngày cam kết tùy ý trên các đối tượng cam kết của mình: ngày đó có thể không phải là điều bạn muốn.
Ciro Santilli 冠状 病毒 审查 事件 法轮功

1
@CiroSantilli 改造 心 心 996ICU đối với tôi dường như chỉ có thể khác nếu trước khi cam kết chung cuối cùng trong cây có một cam kết có dấu thời gian cũ hơn. Bạn có thể cung cấp một ví dụ ít tầm thường hơn?
YakovL

Câu trả lời:


1019

Bạn đang tìm kiếm git merge-base. Sử dụng:

$ git merge-base branch2 branch3
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

85
Lưu ý rằng điều này tìm thấy tổ tiên chung gần đây nhất ... mà tôi tin là những gì người hỏi muốn, vì vậy +1. Chỉ cần lưu ý nó, trong trường hợp bất cứ ai đến đây cố gắng để tìm ra lâu đời nhất tổ tiên chung (như tôi đã làm) - mà, xem thêm: stackoverflow.com/questions/1527234/...
lindes

16
@funroll: Hoặc tốc ký cho điều đó:git log master...HEAD
CB Bailey

17
@lindes tổ tiên chung lâu đời nhất sẽ không phải là cam kết ban đầu?
Thorbjørn Ravn Andersen

8
@ ThorbjørnRavnAndersen, vâng, tôi cho rằng như vậy ... Khó khăn trong mô tả đi kèm với thực tế là git sử dụng đồ thị Acyclic Directed, và nó thường được coi là một cái cây, về mặt kỹ thuật thì không. Để cẩn thận hơn trong cách diễn đạt của tôi, tôi đã nói về trường hợp bạn muốn cha mẹ của phiên bản đầu tiên của "nhánh" phân kỳ ... vì chúng có thể có nhiều điểm trong đó chúng được hợp nhất lại và phân tách lại, đây là "già nhất" trong số này, nhưng không thực sự là tổ tiên lâu đời nhất, mà (tôi nghĩ) luôn luôn là cam kết ban đầu.
lindes 23/2/2015

5
Trong khi câu hỏi này là nghiêm túc về việc tìm ra tổ tiên chung của hai nhánh, bất kỳ ai muốn tổ tiên chung của ba nhánh trở lên nên lưu ý rằng họ cần phải vượt qua --octopuscờ để có kết quả đúng. Rõ ràng nhưng sai git merge-base branch1 branch2 branch3sẽ cung cấp cho bạn một cam kết, nhưng, như được mô tả trong phần Thảo luận trong các tài liệu, nó không nhất thiết là tổ tiên chung của cả ba nhánh.
Đánh dấu Amery

46

git diff master...feature

hiển thị tất cả các cam kết mới của nhánh tính năng hiện tại (có thể là nhiều cam kết) của bạn.

man git-diff tài liệu:

git diff A...B

giống như:

git diff $(git merge-base A B) B

nhưng ...dễ hơn để gõ và nhớ.

Như Dave đã đề cập , trường hợp đặc biệt HEADcó thể được bỏ qua. Vì thế:

git diff master...HEAD

giống như:

git diff master...

Đó là đủ nếu chi nhánh hiện tại là feature.

Cuối cùng, hãy nhớ rằng vấn đề trật tự! Làm git diff feature...mastersẽ hiển thị những thay đổi mà masterkhông phải trên feature.

Tôi muốn nhiều lệnh git sẽ hỗ trợ cú pháp đó, nhưng tôi không nghĩ chúng làm được. Và một số thậm chí có ngữ nghĩa khác nhau cho ...: Sự khác biệt giữa dấu chấm kép ".." và dấu ba chấm "..." trong phạm vi cam kết Git là gì?


8
Hoặc chỉ git diff master...trong trường hợp đặc biệt khác vớiHEAD
Dave

"..." không hoạt động với tôi trong powershell, buồn cười là nó hoạt động trong bảng điều khiển git có lẽ repo chưa hoàn thành, git diff $ (git merge-base AB) B đã làm và vì tôi hơi mới với git Tôi đã có một chút hoài nghi rằng điều này có thể hợp nhất các chi nhánh :)
Moiz Ahmed

1
ồ khá tuyệt. và nếu chi nhánh bạn muốn không tồn tại trong repo địa phương của bạn bởi vì bạn chưa bao giờ kiểm tra nó, bạn chỉ có thể làmgit diff origin/branchname...
Đánh dấu

25

Như đã lưu ý trong câu trả lời trước, git merge-basetác phẩm:

$ git merge-base myfeature develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

nhưng nếu myfeaturelà nhánh hiện tại, như thường thấy, bạn có thể sử dụng --fork-point:

$ git merge-base --fork-point develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

Đối số này chỉ hoạt động trong các phiên bản đủ gần đây của git. Thật không may, nó không luôn luôn hoạt động, tuy nhiên, và không rõ tại sao. Vui lòng tham khảo các giới hạn được ghi nhận vào cuối câu trả lời này .


Để biết thông tin cam kết đầy đủ, hãy xem xét:

$ git log -1 $(git merge-base --fork-point develop) 

Tôi có git version 2.14.1.windows.1. Chạy git merge-base --fork-point branch2với một nhánh (với các cam kết riêng)tôi biết đã rẽ nhánh từ nhánh hiện tại không mang lại kết quả nào, trong khi git merge-base branch1 branch2hiển thị chính xác điểm rẽ nhánh. Điều gì có thể là vấn đề?
ADTC

@ADTC Thanh toán branch2rồi chạy git merge-base --fork-point branch1.
Acumenus

@ADTC Sử dụng trình xem cam kết đồ họa gitk, v.v. để xem cây trông như thế nào. Có lẽ bạn sẽ nhận được câu trả lời của bạn.
Acumenus

Tôi thấy không có gì kỳ lạ về cái cây khi tôi xem nó bằng đồ họa. Tôi có thể theo dõi các đường dẫn và tìm ra tổ tiên chung phù hợp với kết quả của git merge-base branch1 branch2. Nhưng điều kỳ lạ là --fork-pointkhông có gì cả. Bạn đã xác nhận nó hoạt động cho bạn như dự định?
ADTC

1
Tôi nhận được điều tương tự mà @ADTC. Lệnh 'git log -1 $ (git merge-base --fork-point otherBranch)' không hiển thị bất kỳ kết quả nào khi sử dụng git phiên bản 2.16.2.windows.1.
masinger

10

Với gitkbạn có thể xem hai nhánh đồ họa:

gitk branch1 branch2

Và sau đó thật dễ dàng để tìm thấy tổ tiên chung trong lịch sử của hai nhánh.


6
Không phải tất cả mọi thứ có thể được thực hiện trực quan trong mọi trường hợp. Có nhiều lý do tại sao mọi thứ có thể cần phải được tự động hóa theo chương trình.
ADTC
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.