简化,这就是我们发生的事情:
从master
上的此文件开始:
class SomeClass {
...
}
创建分支featureA
off`master。
在featureA
上,将文件更改为:
class SomeClass {
...
}
extension SomeClass {
// implement feature A
}
featureB
off`master。在featureB
上,将文件更改为:
class SomeClass {
...
}
class OtherClass {
// implement feature B
}
featureB
合并到master
。featureA
合并到master
。我们期待的是:
class SomeClass {
...
}
extension SomeClass {
// implement feature A
}
class OtherClass {
// implement feature B
}
或以相反的顺序添加两个,这是公平的 实际上,Git应该报告一个冲突:它不了解语义,并且两个“同时”的变化无法协调。
我们获取的是:
class SomeClass {
...
}
class OtherClass {
// implement feature B
}
没有冲突。也就是说,后来的提交(在另一个之前合并)默默地胜出。
这可以预防吗?怎么样?
注意:如果我使用上述步骤在干净的仓库中尝试此操作,我会在最后一步中遇到合并冲突。因此,问题的根源在于我们在回购中所做的其他事情;暗示赞赏,我看不出会有什么影响。或者问题是差异算法被更复杂的代码绊倒;在生产Swift代码中,我们在一侧有两个扩展,另一侧有嵌套类型的枚举。
答案 0 :(得分:1)
在错误合并的情况下要考虑的主要问题是你可以证明不是人为错误,Git的合并使用Git的差异作为输入。如果差异在普通项目上同步,例如恰好具有右缩进的紧支撑线,Git可以将合并结果放在缩进的位置,因此编译,但是在语义上不合适 - 适合,因此不功能。
如果你说服Git不要在琐事上同步,那么它更有可能发现实际的冲突。您可以通过更改合并时使用的diff算法来完成此操作。您可以尝试使用patience
或histogram
选择-X patience
或-X histogram
算法。有关详细信息的(简短)讨论,请参阅我在周末book进行的非常多进展的第3章(第65页)的结尾。
答案 1 :(得分:1)
使用相同的尝试合并进行一些交叉测试:
git merge
和git merge -s patience
存在冲突。在使用Git 2.11.0和Meld 3.16.0的Mac上,我看到 no 与merge命令冲突。
相反,有
==== BASE ====
}
==== BASE ====
在文件的末尾,所以我认为Meld在这里没有正确解析差异。
似乎那个版本的Meld在解析某些差异时遇到了麻烦。它没有向我展示冲突,所以在将其标记为已解决之前我没有正确修复它。
Nota bene:重现这一点显然需要更多"匹配"线;我的问题中的一个小例子没有做到。
答案 2 :(得分:0)
如您所说,当您尝试单独重现它时,这会恰当地产生冲突。
我最好的猜测是,你的一个分支的开发者将其他开发者分支合并到它自己的分支中,并通过删除第二个类定义来解决冲突。