1 <- 2 <- 5 (merge commit) <- master <- HEAD
\ /
3 <-- 4 <- dev
2
和4
?如果我是对的,那么在哪种情况下使用双向合并?答案 0 :(得分:3)
我认为没有人会真正谈论&#34;双向差异&#34 ;;他们只是&#34;差异&#34;。在实践中,我没有看到短语&#34;三种差异&#34;使用其中之一,但在版本控制中,它是从公共合并基础开始的一对差异的明显标签,查看两个后续但不同的快照。 (您也可以查看&#34; interdiff&#34;。请参阅How do I get the interdiff between these two git commits?和https://linux.die.net/man/1/interdiff。)
术语 merge 具有多种含义,并且在谈论K-way merge sort时(例如,与Git无关)定义明确。但是,当涉及版本控制(比Git更通用)时,短语三向合并非常具体,并且指的是以合并基础开头的合并版本,有两个分歧。
使用版本控制系统已定义&#34;三向合并&#34;这一事实,有些人做了一种back-formation来调用应用单个差异的过程&#34; 2 -way merge&#34;。在我看来,这不是一个好词,因为没有真正的合并。只需称它为“#34;应用差异&#34;或者&#34;应用补丁&#34;。
另见Why is a 3-way merge advantageous over a 2-way merge?请注意,谈论4路甚至5路合并的评论并不适用于Git。
你可以使用git diff --full-index <commit1> <commit2> | git apply -3
让Git对单个文件进行三向合并,其中每个文件的每个合并基本版本都是从index
行单独选择的。但是,这与选择与<commit1>
关联的所有文件作为合并基础基本相同。这种方式的工作方式是git diff
在其输出中打印每个blob的哈希ID,如果git apply
无法按原样应用修补程序,Git将使用打印的blob ID来查找原始然后,从该合并基本版本到该文件的当前版本计算第二个差异。 1 然后将两个差异输入合并机制。 (另请参阅the git merge-file
command。)但请注意, <commit1>
中每个文件的blob哈希值严格由附加到{{的树对象确定。 1}}。因此,与与<commit1>
相关联的文件没有什么不同。也就是说,它有一个例外:如果Git具有提交哈希ID或相应的树ID,Git可以进行树范围的文件比较以查找重命名操作,之后Git可以关联合并基本文件路径 P B ,不同的路径 P L ,&#34;本地&#34;或<commit1>
档案。
换句话说,--ours
和git diff --full-index <parent> <child> | git apply -3
之间的主要区别在于前者在后退期间不会检测重命名&#34;三向补丁&#34;操作,如果没有它可以执行补丁应用,甚至不会尝试在任何一个文件上进行三向合并。我认为,很难(但并非不可能)构建人为的例子,这些例子会产生截然不同的结果,但我现在没有时间做这件事。
1 事情变得有点复杂,因为&#34;当前版本&#34;不一定是HEAD版本。具体而言,git cherry-pick <child>
使用工作树版本作为git apply
变体,而--ours
使用索引版本作为git apply --index
变体。但是,--ours
命令要求索引和工作树是&#34; clean&#34;默认情况下,即匹配git cherry-pick
提交。在这种情况下,&#34; HEAD版本&#34;,&#34;索引版本&#34;和&#34;工作树版本&#34;通常没有区别。< / p>