什么是二路和三路差异/合并?

Sta*_*lfi 4 git

1 <- 2 <- 5 (merge commit) <- master <- HEAD
 \       /
  3 <-- 4 <- dev
Run Code Online (Sandbox Code Playgroud)
  1. 双向合并是否仅使用提交24合并期间?如果我是对的,那么在什么情况下使用双向合并?
  2. 什么是双向差异?
  3. 什么是三向差速器?

tor*_*rek 5

我认为没有人真正谈论“双向差异”;它们只是“差异”。在实践中,我也没有看到使用“三向差异”一词,但在版本控制中,它是从公共合并基础开始的一对差异的明显标签,查看两个后续但不同的快照。(您也可以查找“interdiff”。请参阅如何获取这两个 git 提交之间的 interdiff?https://linux.die.net/man/1/interdiff。)

术语“合并”有多种含义,并且(例如,与 Git 无关)在谈论K 路合并排序时有明确的定义。然而,当涉及到版本控制(比 Git 更通用)时,三向合并这个短语非常具体,指的是从合并基础版本开始的合并,与此有两个分歧。

利用版本控制系统定义了“三向合并”这一事实,一些人制作了一种反向构造,将应用单个差异的过程称为“双向合并”。在我看来,这不是一个好术语,因为没有真正的合并发生。称之为“应用差异”或“应用补丁”。

另请参阅为什么 3 路合并比 2 路合并更有优势? 请注意,谈论 4 甚至 5 路合并的评论并不真正适用于 Git。

可以使用git diff --full-index <commit1> <commit2> | git apply -3Git 对各个文件进行三向合并,其中每个文件的每个合并基础版本都是从行中单独选择的index<commit1>但是,这本质上与选择 关联的所有文件作为合并基础相同。其工作原理是git diff在其输出中打印每个 blob 的哈希 ID,如果git apply无法按原样应用补丁,Git 将使用打印的 blob ID 来定位原始文件,然后计算该合并的第二个差异基本版本到文件的当前版本。1 然后将两个差异输入合并机制。(另请参见命令git merge-file。 )但请注意, 每个文件的 blob 哈希值严格由附加到 的<commit1>对象确定。因此,这与说. 也就是说,这与一个例外没有什么不同:如果 Git 具有提交哈希 ID,或者相应的树 ID,Git 可以进行树范围的文件比较以查找重命名操作,之后 Git 可以关联合并基础的文件路径P B具有不同的路径P L,即“本地”或文件。<commit1><commit1>--ours

换句话说,git diff --full-index <parent> <child> | git apply -3和之间的主要区别git cherry-pick <child>在于,前者不会在后备“三向补丁”操作期间检测重命名,并且如果能够执行以下操作,甚至不会尝试对任何一个文件进行三向合并:没有那个补丁应用程序。我认为,构建人工示例(其中这些示例会产生非常不同的结果)很困难(但并非不可能),但我现在没有时间这样做。


1这里事情变得有点复杂,因为“当前版本”不一定是 HEAD 版本。具体来说,git apply使用工作树版本作为--ours变体,而git apply --index使用索引版本作为--ours变体。然而,该git cherry-pick命令要求索引和工作树默认是“干净的”,即与提交匹配HEAD。在这种情况下,“HEAD 版本”、“索引版本”和“工作树版本”之间通常没有区别。