维基百科说 3 路合并比 2 路合并更不容易出错,而且通常不需要用户干预。为什么会这样?
一个 3 路合并成功而 2 路合并失败的示例会很有帮助。
维基百科说 3 路合并比 2 路合并更不容易出错,而且通常不需要用户干预。为什么会这样?
一个 3 路合并成功而 2 路合并失败的示例会很有帮助。
假设您和您的朋友都签出了一个文件,并对其进行了一些更改。您在开头删除了一行,而您的朋友在末尾添加了一行。然后他提交了他的文件,您需要将他的更改合并到您的副本中。
如果您正在执行双向合并(换句话说,差异),该工具可以比较两个文件,并看到第一行和最后一行不同。但是它怎么知道如何处理这些差异呢?合并后的版本应该包括第一行吗?它应该包括最后一行吗?
通过三向合并,它可以比较两个文件,但它也可以将每个文件与原始副本进行比较(在你们中的任何一个更改之前)。所以它可以看到您删除了第一行,而您的朋友添加了最后一行。它可以使用该信息来生成合并版本。
这张来自 perforce 演示文稿的幻灯片很有趣:
三路合并工具的基本逻辑很简单:
- 比较基础文件、源文件和目标文件
- 识别源文件和目标文件文件中的“块”:
- 与基础不匹配的块
- 与基础匹配的块
- 然后,将合并的结果放在一起,包括:
- 在所有 3 个文件中相互匹配的块
- 与源或目标中的基础不匹配但两者都不匹配的块
- 与基础不匹配但相互匹配的块(即,它们在源和目标中的更改方式相同)
- 冲突块的占位符,由用户解决。
请注意,此插图中的“块”纯粹是象征性的。每个都可以表示文件中的行,或层次结构中的节点,甚至是目录中的文件。这一切都取决于特定的合并工具能够做什么。
您可能会问 3 路合并比 2 路合并有什么优势。实际上,没有双向合并之类的东西,只有区分两个文件并允许您通过从一个文件或另一个文件中选择块来“合并”的工具。
只有 3-way 合并让您能够知道一个块是否是对原点的更改以及更改是否冲突。
三向合并是在应用一个基本文件的两个变更集时合并它们,而不是应用一个,然后将结果与另一个合并。
例如,在同一位置添加一行的两个更改可以解释为两个添加,而不是一行的更改。
比如文件a
已经被两个人修改过,一个添加moose
,一个添加mouse
。
#File a
dog
cat
#diff b, a
dog
+++ mouse
cat
#diff c, a
dog
+++ moose
cat
现在,如果我们在应用变更集时合并它们,我们将得到 (3-way merge)
#diff b and c, a
dog
+++ mouse
+++ moose
cat
但是如果我们应用 b,然后看看从 b 到 c 的变化,看起来我们只是将 'u' 更改为 'o'(2 路合并)
#diff b, c
dog
--- mouse
+++ moose
cat