[英]Determine commits introduced to branch by merge commit in git?
我试图确定由于使用合并ID合并而引入父分支的提交。
命令git log <id>~1..<id>
将列出所有合并的提交,以及合并提交本身。
使用max630的答案 ,只要它是真正的合并。 要排除合并本身,请使用它的略微变体: M^1..M^2
。
你在这里要求的是找到由于合并而变得可以访问的提交。 这种可达性理念是图论理论的概念。 因此,如果您绘制合并的结果,答案就更清楚了。
假设“合并前”图形如下所示,其中*
是合并基础提交, L
和R
是左侧和右侧提示:
...--*--...--L <-- mainline
\
o--...--R <-- sidebranch
然后“合并后”图形如下所示:
...--*--...--L---M <-- mainline
\ /
o--...--R <-- sidebranch
现在很明显,新引入的提交是:-)沿底行的那些,即可从(包括) R
到达的那些,但不包括合并库提交。 我们通过从M
的第二个父节点(即R
开始到达它们,然后沿着从R
到其父节点的向后连接,到另一个父节点,等等。 这些导致底部o
节点,它连接回commit *
。
如果你的名字像sidebranch
指向R
,你只需要找到合并基础:
mb=$(git merge-base $all mainline^1 sidebranch)
它使用“提交的第一个父”语法来识别来自提交M
提交L
: ^1
后缀。 如果您不再使用名称sidebranch
,则可以使用“提交的第二个父”语法来标识提交R
:
mb=$(git merge-base $all mainline^1 mainline^2)
不幸的是,这不是唯一可能的输入图。 拥有“合并前”图形非常典型,如下所示:
...--* <-- mainline
\
o--...--R <-- sidebranch
在没有--no-ff
情况下运行git merge
将执行“快进”操作,这实际上不是合并:最终得到一个线性图并且没有合并提交:
...--*--o--...--R <-- mainline, sidebranch
在这里,除非您仍然拥有主线分支的reflog条目,否则几乎不可能找到commit *
。 如果你有引用日志条目,它很简单:它是mainline@{ number }
,使用适当的number
。 (找到适当的number
是通过查看reflog来查找来自快进的更新的问题。如果你刚刚进行了合并,它只是1
并且也是HEAD@{1}
。)
mb=$(git rev-parse mainline@{1}) # for instance
我将$all
放在上面找到合并库的示例命令中的原因是,当你有多个合并库时,还有第三种可能性:
...--o--*---o--...--L
\ /
X
/ \
...--o--*---o--...--R
在这里,您将要排除所有合并基础。 如有必要,用--all
替换$all
。
现在您已经了解了合并库,如果合并是真正的合并,那么使用git merge-base
找到它们, git merge-base
可以访问的提交只是可以从R
本身访问的提交,而不是来自合并库的提交(S):
git rev-list sidebranch --not $mb
如果要检查提交而不是简单地枚举它们,请使用git log
而不是git rev-list
。
以上所有内容旨在找到合并基础并将其排除,以便我们获得提交R
及其可访问的祖先,而无需从L
获得任何提交。 但我们不必特别从合并基础开始这种排除。 我们可以从L
本身开始。
要命名L
,我们只需要命名mainline
的先前值或合并M
的第一个父级。 M
的第一个父是M^1
或M~1
,所以只要我们知道M
的哈希ID,我们就可以添加后缀并说“排除这些”。
甚至还有一个简短的语法。 代替:
git rev-list M^2 --not M^1
或略短:
git rev-list M^2 ^M^1
我们可以使用双点语法:
git rev-list M^1..M^2
这就是我们在顶部所拥有的。
请注意,所有这些都假设为“真正合并”:如果合并是快进,则必须使用reflog。
您可以签出分支并使用git log查看分支中的提交和提交ID。 git log -n10 --oneline
将为您提供该分支中前10次提交的历史记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.