Git:查找两个分支机构的最新共同祖先


844

如何找到两个Git分支的最新共同祖先?


3
定义最新时间:实际时间,提交次数,其他指标?
Ciro Santilli冠状病毒审查六四事件法轮功

2
相关(纵横交错合并):stackoverflow.com/questions/26370185/...
jub0bs

1
@CiroSantilli新疆改造中心996ICU六四事件在任何度量标准上都是一样的,不是吗?
YakovL

@YakovL我相信没有,因为分支,而且因为您可以在提交对象上设置任意提交日期:该日期本身可能不是您想要的。
Ciro Santilli冠状病毒审查六四事件法轮功

1
@CiroSantilli新疆改造中心996ICU六四事件在我看来,只有在树中的最后一个公共提交之前,存在具有较旧时间戳记的提交,这才可能有所不同。您能提供一个简单的例子吗?
YakovL

Answers:


1019

您正在寻找git merge-base。用法:

$ git merge-base branch2 branch3
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

85
请注意,这找到了最近的共同祖先...我相信这是发问者想要的,所以+1。只要注意到它,万一有人来这里试图找到最古老的共同祖先(像我一样) -对此,另见:stackoverflow.com/questions/1527234/...
lindes

16
@funroll:或简称:git log master...HEAD
CB Bailey

17
@lindes将不是最早的共同祖先?
托尔比约恩Ravn的安徒生

8
@ThorbjørnRavnAndersen,是的,我想是这样...描述上的困难来自git使用有向无环图的事实,但它通常被认为是一棵树,从技术上讲并不是这样。为了更加谨慎,我在谈论的情况是您希望“分支”的第一个实例的父级分开...因为它们可能在多个位置重新合并和拆分,这是其中“最老的”,但并不是真正的最老的祖先,(我认为)始终是最初的提交。
林德斯

5
虽然这个问题严格来说是关于找到两个分支的共同祖先,但是任何想要三个或更多分支的共同祖先的人都应该注意,他们需要通过--octopus标记才能获得正确的结果。最明显的,但是,错了git merge-base branch1 branch2 branch3会给你一个承诺,但是,在文档的讨论部分所描述的,它并不一定是所有三个部门的一个共同的祖先。
Mark Amery

46

git diff master...feature

显示当前(可能是多次提交)功能分支的所有新提交。

man git-diff 证明文件:

git diff A...B

是相同的:

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

...更容易键入和记住。

Dave所述,HEAD可以省略的特殊情况。所以:

git diff master...HEAD

是相同的:

git diff master...

如果当前分支为,这就足够了feature

最后,请记住顺序很重要!这样做git diff feature...master会显示master未启用的更改feature

我希望更多的git命令支持该语法,但我认为它们不支持。有些甚至具有不同的语义...Git提交范围中的双点“ ..”和三点“ ...”之间有什么区别?


8
或者只是git diff master...在版本比较到的特殊情况HEAD
戴夫

“ ...”在powershell中对我不起作用,有趣的是它在git控制台中起作用,也许回购未完成,git diff $(git merge-base AB)B起作用了,因为我对git有点陌生我对此可能会合并表示怀疑:)
Moiz Ahmed '18

1
哇。太神奇了。如果您想要的分支在本地存储库中不存在,因为您从未签出过,则可以简单地做一下git diff origin/branchname...
Mark Ch

25

如先前的回答所述,git merge-base可以:

$ git merge-base myfeature develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

但是,如果myfeature是当前分支(通常),则可以使用use --fork-point

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

此参数仅在最新版本的git中有效。不幸的是,它并不总是有效,并且不清楚原因。请参阅此答案结尾处指出的限制。


有关完整的提交信息,请考虑:

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

我有git version 2.14.1.windows.1。运行git merge-base --fork-point branch2一个分支(有自己的提交),我知道,从当前分支叉不会产生任何结果,而git merge-base branch1 branch2正确显示叉点。可能是什么问题呢?
ADTC

@ADTC Checkout branch2,然后运行git merge-base --fork-point branch1
Acumenus

@ADTC使用图形提交查看器,例如gitk,等等,以查看树的外观。也许您会得到答案。
Acumenus

当我以图形方式查看它时,我发现这棵树没有什么奇怪的。我可以跟踪路径并找到与的结果匹配的公共祖先git merge-base branch1 branch2。但是奇怪的是,--fork-point这两种方式都不给任何结果。您是否已确认它可以按预期工作?
ADTC

1
我得到的与@ADTC相同。使用git版本2.16.2.windows.1。时,命令'git log -1 $(git merge-base --fork-point anotherBranch)'不会显示任何结果。
Masinger

10

随着gitk您可以图形方式查看两个分支:

gitk branch1 branch2

然后很容易在两个分支的历史中找到共同的祖先。


6
并非在每种情况下都可以通过视觉完成所有操作。出于某些原因,可能需要以编程方式使事情自动化。
ADTC
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.