## 命名

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