git merge-base
命名
git-merge-base - 为合并找到尽可能好的共同祖先
概要
git merge-base [-a|--all] <commit> <commit>… git merge-base [-a|--all] --octopus <commit>… git merge-base --is-ancestor <commit> <commit>git merge-base --independent <commit>… git merge-base --fork-point <ref> [<commit>]
描述
git merge-base
在两次提交之间找到最佳共同祖先以用于三向合并。better
如果后者是前者的祖先,一个共同的祖先是另一个共同的祖先。一个没有任何更好的共同祖先的共同祖先是a best common ancestor
,即a merge base
。请注意,一对提交可能有多个合并基础。
操作模式
作为最常见的特例,在命令行中只指定两个提交意味着计算给定两个提交之间的合并基础。
更一般地说,在计算合并基数的两个提交中,有一个由命令行上的第一个提交参数指定; 另一个提交是一个(可能是假设的)提交,它是命令行上所有其余提交的合并。
因此,merge base
如果指定了两个以上的提交,则不一定包含在每个提交参数中。这与使用该--merge-base
选项时不同于git-show-branch [1] 。
--octopus
计算所有提交的提交的最佳共同祖先,准备进行n路合并。这模仿的行为git show-branch --merge-base
。
--independent
不是打印合并基础,而是使用相同的祖先打印提供的提交的最小子集。换句话说,在提交的提交中,列出那些无法从其他提供的提交。这模仿的行为git show-branch --independent
。
--is-ancestor
检查第一个<commit>是否是第二个<commit>的祖先,如果为true,则退出状态0,否则退出状态1。错误通过不为1的非零状态发出信号。
--fork-point
查找分支(或任何导致<commit>的历史记录)从另一个分支(或任何引用)<ref>分支的点。这不仅仅是寻找两个提交的共同祖先,而且还考虑了<ref>的引用日志,以查看引用<commit>的历史是否来自分支的早期化身<ref>(参见下面的这个模式)。
选项
-a --all
输出提交的所有合并基础,而不仅仅是一个。
讨论
给定两个提交A
和B
,git merge-base A B
将输出一个提交这从到达A
和B
通过父关系。
例如,对于这种拓扑结构:
o---o---o---B /---o---1---o---o---o---A
A
和B
之间的合并基础是1
。
鉴于三个提交A
,B
并且C
,git merge-base A B C
将计算之间的合并基础A
和假设的承诺M
,这是之间的合并B
和C
。例如,对于这种拓扑结构:
o---o---o---o---C / / o---o---o---B / /---2---1---o---o---o---A
结果git merge-base A B C
是1
。这是因为合并相当于拓扑承诺M
之间B
和C
为:
o---o---o---o---o / \ / o---o---o---o---M / /---2---1---o---o---o---A
结果git merge-base A M
是1
。提交2
也是之间一个共同的祖先A
和M
,不过1
是一个更好的共同的祖先,因为2
是的祖先1
。因此,2
不是合并基础。
结果git merge-base --octopus A B C
是2
,因为2
是所有提交的最佳共同祖先。
当历史涉及纵横交错时best
,两个提交可以有多个共同的祖先。例如,对于这种拓扑结构:
---1---o---A \ / X / \---2---o---o---B
两个1
和2
是A的合并底座和B.既不一个比另一个(均为更好best
合并碱基)。如果--all
没有给出选项,则没有指定哪一个输出最好。
检查两个提交A和B之间的“快速前进”的常见方法是(或者至少用于)计算A和B之间的合并基础,并检查它是否与A相同,在这种情况下,A是B的祖先。你会在老的脚本中看到这种习惯用法。
A=$(git rev-parse --verify A)if test "$A" = "$(git merge-base A B)"then ... A is an ancestor of B ...fi
在现代的git中,你可以用更直接的方式来说明这一点:
if git merge-base --is-ancestor A B then ... A is an ancestor of B ...fi
代替。
讨论叉点模式
在topic
创建分支之后git checkout -b topic origin/master
,远程跟踪分支的历史origin/master
可能已经被重新卷绕和重建,导致这种形状的历史记录:
o---B1 /---o---o---B2--o---o---o---B (origin/master) \ B3 \ Derived (topic)
在那里origin/master
用于指向提交B3,B2,B1,现在它指向B,并且当你在B3 topic
时,你的分支在它的顶部被启动origin/master
。此模式使用reflog origin/master
来查找B3作为分叉点,以便topic
可以在更新origin/master
的基础上重新绑定:
$ fork_point=$(git merge-base --fork-point origin/master topic)$ git rebase --onto origin/master $fork_point topic