合并不会保留对文件的更改,为什么?

时间:2017-06-30 15:53:52

标签: git merge

我遇到过这样一种情况:merge默默地忽略了合并分支的一些变化,我期望(rebase会接受它们)。

情况如下:

*    merge slave into master: line not back
|\
| *  oops, was bad, put the line back (slave branch)
| |
| *  slave branch, also delete the same line
* |  master branch, delete a line
|/
*  initial

slave合并到master时,该行仍然被删除,因此将其放回的提交未合并。反叛者会。

如果该线路未被移除但被修改,这将是一个冲突,这对我来说没问题。一个rebase会接受这条线,也没关系。但是完全没有警告地跳过提交......我想知道它的设计是针对哪些情况。

注意:在网上搜索类似的问题发现很多......但是所有关于在合并之前删除的整个文件都是如此。我可以承认这个原因,即使我更喜欢冲突(而不是丢失提交)。但是,对于文件内部的更改,我发现这更令人不安,并且没有提及。

注意:我在Mercurial上查了一下,结果相同,这不是Git特有的。

1 个答案:

答案 0 :(得分:2)

原因是(文件级)合并没有看到变化的路径;它会看到该文件的三个版本:baseourstheirs

如果分支删除了一条线然后将其放回,theirsbase是相同的(至少在相关的行上)。事实上,合并工具不知道theirs历史中某些线条不相同的事实。

因此,对于theirs,该行不是已更改的块的一部分;但对ours而言,ours的更改已被接受。

我同意它不是你想要的特定合并,但我看不出任何合理有效的方法来做得更好。此外,在18年多的编程中,我从未遇到过这种情况 - 所以"令人不安的"可能有点强大。

(我还要注意,你对此的描述为"失去提交"并不是真的准确。提交 包含在合并结果中,只是在一个适得其反的方式。最重要的是,自动合并算法永远不会是完美的;但我们使用的算法在大多数时候都非常好。)

我想如果你真的想要记住分支机构考虑如何处理这条线并决定保留它的事实,你可以做出一些无意义的事情。更改为恢复的行。然后,当您注意到更改行的情况时,它将出现冲突。

但实际上,你进行单元测试,不是吗?如果这条线足够重要,可以在两个更改行中删除并重新添加到其中一个更改行中,那么如果处理错误,您的测试用例肯定会失败吗?你知道要测试你的合并结果吗?

重点是,它不是该工具的良好行为......但它是一种罕见的不良行为,无论如何都应该在成熟的开发过程中捕获和纠正。我不会读太多内容。