经过多次试验,我得到了这个简单的测试案例场景:
a --> b --> c -- (master)
\ \
--> d --> b' --> e (branch)
其中:
b'
是b
e
是来自master
的合并。 b'
在c
之后完成,c
修改了与b
相同的文件(d
可能无关紧要。)
e
很容易看起来很意外。
假设所有'他们正在处理相同的文件“foobar.txt
”。这是文件在每次提交中的显示方式:
// ----------- a
foo
delme
bar
// ----------- b
foo
delme
new
bar
// ----------- c
foo
new
bar
// ----------- b'
foo
delme
new
bar
// ------------ e
foo
new
new
bar
现在,这是我刚才的简短测试,这个完全设置。
如果您删除了所有spaces,则没有此类问题。正如我所料,合并只会指责冲突。但我不认为在这里使用任何-X设置空间是我们正在寻找的......或者是它?
与此同时,在我的生产代码中,这就是我开始研究这一切的原因,并且没有那么多空格,我得看e
看起来像这样:
// ----------- e
foo
delme
new
bar
合并所发生的一切都不会引发任何冲突!
如果git要在这里做任何巫术魔法自动合并,这就是我期望的样子:
// ----------- e
foo
new
bar
但这也不会发生。
有点像免责声明 ......
我也试过reading the f manual,但我无法理解合并策略下的太多要点。此外,它并没有真正说明resolve
策略在幕后做了什么,例如:
它试图仔细检测纵横交错的合并模糊性,并且通常被认为是安全和快速的。
没有说什么。
有关默认recursive
的文字较大,但我也无法从中提取足够的信息:
据报道,这可以减少合并冲突,而不会因为从Linux 2.6内核开发历史记录中进行的实际合并提交而导致错误合并。
报告?所以我们得到了一个非常重的单元测试,并且通过一些报告假设它没问题?
嗯,这对我来说太模糊了。
我认为我一定做错了什么!那么,我该怎么做呢?
我需要做些什么来重新合并而不用担心?
答案 0 :(得分:24)
基本问题在于没有正式的模型来确定在每种情况下做正确的自动合并的意义。实际上,对于不同的用例,“合适的东西”可以以合并算法不知道的方式而不同。已经有各种各样的尝试想出一个单一的,正确的合并算法,总是做正确的事情(各种Monotone合并策略,Codeville,Precise Codeville,Darcs等),并且所有这些都在某种程度上失败了现实世界的用例。
因此,对于真实世界的合并算法“它在具有大量合并的真实代码库上运行良好”是关于你能够做到的最好的。这意味着您永远不应盲目相信干净的自动合并的结果;虽然它可能已经干净地合并而没有冲突,但这可能并没有完全符合您的预期。您仍然需要查看合并的内容,并测试结果。
我的一般方法是尝试几个不同的合并选项,就像你一样,看看其中一个是否产生了正确的合并。如果这不能帮助您获得正确的合并(或产生您可以解决的适当冲突的合并),那么您应该执行git merge --no-commit
,并在提交之前根据需要修复合并。