我正在阅读this:
在这种情况下,Git使用两者进行简单的三向合并 分支提示指向的快照和共同的祖先 2。
典型合并中使用的三个快照。图3-16。三个快照 用于典型的合并而不仅仅是移动分支指针 转发,Git创建一个由这个三向产生的新快照 合并并自动创建指向它的新提交。这个 被称为合并提交,并且特别在于它具有更多 而不是一个父母。
这两个提示有意义......但为什么你需要共同的祖先?
答案 0 :(得分:2)
Git需要知道每个分支中发生了什么变化,所以让我们说master
更改文件A,iss53
更改文件B.没有找到共同的祖先,Git只会知道这两个文件A和B在提示中有所不同,但不能选择哪个版本的A和B.
通过将提示与共同祖先进行比较,Git可以可靠地看到A iss53
没有变化,因此使用master
的A版本,反之亦然。“ p>
当两个分支修改同一个文件时,事情会变得更复杂,但这应该澄清事情。
答案 1 :(得分:1)
如果您查看three-way merge的实际含义,则应该更清楚地了解共同祖先。
使用图中的节点标签,假设您的仓库有一个文件foo
。
在提交C2
(共同祖先)中,foo
包含:
a
b
c
在提交C4
中,foo
更改为:
aa
b
c
在提交C5
中,foo
更改为:
a
b
cc
合并C4
和C5
应该没有冲突,导致:
aa
b
cc
以第1行为例,在不考虑共同祖先的情况下,Git只会知道此行在提交C4
和C5
之间是不同的,但不会知道哪个版本(a
或aa
)应保留在合并结果中,因此Git必须将其标记为合并冲突。为了解决冲突,用户必须将在共同祖先出现的foo
与在foo
和C4
中出现的C5
进行比较。由于第1行仅在其中一项提交(C4
)中进行了更改,因此应保留更改(aa
)。通过考虑共同祖先,Git可以自动执行此步骤。
如果C5
也更改了第1行(例如,更改为aaaa
),那么Git不会知道最好保留哪个版本。这将导致用户需要手动解决的合并冲突。
答案 2 :(得分:-1)
主要原因是因为git没有合并tip-to-tip。相反,它以递增方式合并分支到分支。含义:它分别合并每个分支中的每个提交。
在上面的示例中,git不直接合并C4和C5。相反,它首先合并C3和C4,然后它合并C5和C4。为了做到这一点,它必须找出它开始合并的位置。它是从C0开始的吗?它是以C1开始的吗?确定从哪里开始合并的过程就是寻找共同的祖先。
为什么git以这种方式合并?
因为事实证明它是以最少的合并冲突*结束的技术。以前的源代码控制系统只执行diff-patch进程,这往往会产生大量的合并冲突。
*注意:事实上,git使用的确切算法(合并顺序)是作为插件实现的,因此您可以自由选择多种算法,以根据您的工作流程减少合并冲突。