git merge的合并策略

概述

git merge 的合并策略分为两种 —— fast-forward 和“三方合并”。fast-forward 合并策略的使用场景及具体操作已经介绍于 git 分支操作,本文主要介绍“三方合并”相关内容。

三方合并

如果当前分支不是待合并分支的前驱,此时便不会执行 fast-forward 合并策略,而是执行“三方合并” (以当前分支所在快照、待合并分支所在快照、两分支最近公共祖先所在快照为依据,实施合并)。

图一:三方合并场景

在介绍“三方合并”之前,我们先行谈谈为什么不能使用“二方合并” (以当前分支所在快照、待合并分支所在快照为依据,实施合并)?

为回答这个问题,我们使用例子进行说明。

假定需要合并文件 1bdd3be5d6c1b0e2,且其内容展示如下:

通过对比两个文件,我们发现第1,2,4,5行内容不同,便认为这些地方所示内容冲突。如果仅根据此冲突信息进行合并,那么将会得到:

1
2
3
4
5
6
7
8
9
10
11
12
<<<<<<< HEAD
1
=======
5
>>>>>>> branch
<<<<<<< HEAD
2
=======
4
>>>>>>> branch
3
...

仔细观察合并文件,可以发现:它仅提供了冲突信息,并没有任何合并功能的体现。由此我们可以得出结论:仅提供当前分支所在快照、待合并分支所在快照信息,而不提供任何上下文信息,无法执行合并操作

在“三方合并”之中,它需要两分支最近公共祖先所在快照信息,从而据此提供上下文信息,并以此顺利实现合并操作。

假定需要合并文件 1bdd3be5d6c1b0e2,并且两者祖先文件为 ba8beb31,三者内容展示如下:

基于祖先文件内容,我们可以得知当前文件对祖先文件进行了哪些修改 (使用 ‘*’ 加以标记):

对于待合并文件而言,如果一者某部分内容已修改而另一者未曾修改,则合并后的内容为修改后的内容;如果两者均已修改,则需显示冲突信息,等待用户自己决定应当保留哪部分数据。根据此原则,合并后的文件内容如下:

注意:最近公共祖先所在快照信息的不同,可能会引发不同的合并结果。