为什么使用Git的合并似乎有冲突? [英] Why does a seemingly possible merge using Git have conflicts?
问题描述
简而言之,为什么文件foo.txt
具有内容
In short, why does a file foo.txt
having content
a
b
无法与具有内容的foo.txt
的分支合并:
failed to merge with the branch with foo.txt
having content:
a
c
?
更长的版本是:为了试验Git和合并,我做了以下工作:
The longer version is: to experiment with Git and merging, I did the following:
-
mkdir
一个新目录,并cd
进入该目录并git init
- 创建文件
foo.txt
并添加行a
(第一次是这样,第二次是在a
之后有2个空行) - 提交,现在
git checkout -b feature
和git checkout -b sprint
(据我所知,连续执行而不是先切换回master
并创建sprint
并没有什么区别,因为分支是基于commitID创建的,无论哪种情况,它们都是完全相同的. - 现在
git co feature
,使文件看起来像a
,然后是空行,然后是第三行中的c
- 现在提交它,并执行
git checkout sprint
,使文件看起来像a
,然后单独显示下一行b
. - 现在提交它,现在执行
git merge feature
mkdir
a new directory andcd
into it andgit init
- create a file
foo.txt
and add the linea
(first time just like that, and second time with 2 empty lines aftera
) - commit it, and now
git checkout -b feature
andgit checkout -b sprint
(so as far as I know, it makes no difference to do it in a row instead of first switching back tomaster
and createsprint
, because branches are created based on commitID, and either case, they are exactly the same. - Now
git co feature
and make the file look likea
and then empty line and thenc
on the third line - Now commit it, and do
git checkout sprint
and make the file look likea
and then next lineb
on its own. - Now commit it, and now do a
git merge feature
并且据说,合并可能已经成功完成,其中包含内容
and supposedly, the merge could have succeeded, with the content
a
b
c
但是为什么失败了?除了猜测也许线条太紧密"之外,还可以给出来自文档或参考的更明确的答案吗?
but why did it fail? Instead of guessing "maybe the lines are too close", can a more definitive answer from docs or reference be given?
我还尝试在a
和b
之间以及b
和c
之间添加空行,以便它们之间的间距更大,但是在foo.txt
的第一个版本中没有初始空行,结果是一样的:合并冲突.
I also tried adding an empty line between a
and b
, and between b
and c
so they are more spaced out, but without the initial empty lines in the first version of foo.txt
, and the result was the same: merge conflict.
推荐答案
在您定位时,它们太接近了.我们使用没有空行的公共祖先来避免混淆.如果您有一些共同的祖先:
As you posit, they're too close. Let's use a common-ancestor that doesn't have empty lines to avoid confusion. If you have some common ancestor:
line 1
line 2
line 3
line 4
然后您编辑双方:
line 1
LINE TWO
line 3
line 4
并且:
line 1
line 2
LINE THREE
line 4
然后git diff/merge引擎(xdiff)将产生冲突.尽管我找不到关于此的文档,但显然可以凭经验看到.这是一个实现细节,尽管很常见.
Then the git diff/merge engine (xdiff) will produce a conflict. Though I could not find documentation on this, it can obviously be seen empirically. This is an implementation detail, though a common one.
如果您认为自动合并描述的是更改区域,是相对于其他区域(而不是用数字表示的行)描述的,则这可能更有意义:第一面更改line 1
之后和line 3
之前的数据.第二面更改line 2
之后和line 4
之前的数据.
If you think of the automerge as describing changed regions, described in relation to other regions (instead of lines, addressed by numbers) this might make more sense: the first side changes data after line 1
and before line 3
. The second side changes data after line 2
and before line 4
.
但是,当您尝试将这些更改关联起来时,您会遇到麻烦:第一面已删除了第二面用来描述其变化的上下文(line 3
).
When you try to correlate these changes, though, you run into trouble: the first side has removed the context (line 3
) that the second side relies on to describe its changes.
只要存在某些上下文(即,更改不是太接近"),即使该上下文是一行,它也应该起作用.如果您的共同祖先是,请将您的示例扩展到您不会改变紧邻的行的地方,
As long as there's some context (ie, the changes are not "too close") this should work, even if that context is a single line. To extend your example to where you are not changing immediately adjacent lines, if your common ancestor is:
a
d
一侧是:
a
b
d
另一面是:
a
c
d
然后它将成功自动合并为:
Then this will automerge successfully as:
a
b
c
d
这篇关于为什么使用Git的合并似乎有冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!