什么是
必要且充分的条件,和/或
所有案件或一些常见案件
会导致git merge
报告合并冲突吗?
git merge
如何确定一行或一些行是否包含
合并冲突?
例如,我有时会看到如下情况,其中一种情况
中的Part 1
或Part 2
为空
<<<<<<< HEAD
(Part 1)
=======
(Part 2)
>>>>>>> some-other-branch
看起来不太可能与我发生合并冲突。那么有什么可能的原因呢 这样的案件有合并冲突吗?
比较git merge
报告的合并冲突
git diff
报告的差异是否正确
git diff
报告的差异可能不一定在git merge
报告的合并冲突的位置,
git merge
报告的合并冲突可能不一定在git
diff
报告的差异的位置?
感谢。
答案 0 :(得分:8)
完整正确的答案有多个部分。首先,我们必须首先进行正常的三向合并(在Git中需要使用-s recursive
或-s resolve
,如果使用-s recursive
,则需要找到一个合并基数和两个其他承诺)。但是,您可能希望跳到第三部分。
要完成任何合并,您需要:
HEAD
) B 作为祖先,因为&#34;是祖先&#34;允许在提交图中的节点相等(技术上它是先前或相等的比较),它可能有 B = L 和/或 B = R 。但是,如果是这种情况,则不需要合并 ,如果强制进行合并(使用git merge --no-ff
- 这意味着 B = L 和L≺R;两个非强制案例是&#34;快进&#34;不实际合并和&#34;没什么要合并&#34;错误)没有合并冲突。因此,我们可以假设合并基础位于合并的两侧之前。
1 使用--allow-unrelated-histories
,如果 L 和 R 没有最低共同的祖先节点。但是,这会导致所有已识别的文件添加/添加冲突。
接下来,要在某个文件路径中出现冲突,您需要我称之为&#34;高级别&#34;冲突或低水平&#34;冲突(或两者兼而有之)。为此,Git必须识别 B ( L , L 和 R 中的(即匹配在一起)文件。由于能够添加新文件,重命名文件和删除文件,因此不要求文件在所有三次提交中都具有相同名称。特别是:
path/to/foo.txt
,其匹配 P L path/to/foo.txt
和 P R path/to/foo.txt
。显然这个文件是&#34;同一个文件&#34;整个合并,因此Git将这三个路径标识为一个文件。)path/to/basename
, P L path2/to2/left
, P R path3/to3/right
。这些中的一个或多个可能甚至不存在。这导致:添加/添加冲突,如果∄ P B 和 P L = P R ;重命名/删除冲突,如果 P B 等于左路径或右路径之一,但另一路径不存在;或重命名/重命名冲突,如果 P B ≠P L ≠P R 。如果还没有高级别冲突(添加/添加,重命名/重命名或重命名/删除),则可能仍存在重命名/修改或重命名/删除冲突,只要blob的哈希ID由两个或三个路径名称命名的(文件内容)不匹配。
所有这些&#34;高水平&#34;冲突导致合并冲突,但不会导致任何冲突标记。为此,我们现在必须将基本文件与两个侧文件合并(这意味着所有三个文件必须存在,或者对于添加/添加案例,我们将一个简单的空文件作为基本版本)。
此合并可能有也可能没有自己的冲突。如果合并增加了低级别冲突,我们将获得冲突标记。如果没有高级别冲突(所有三次提交中的路径相同)但需要完全合并(哈希值各不相同),我们可能会与冲突标记发生低级冲突。
要在工作树中的一个文件中获得合并冲突,Git必须看到左侧和右侧版本都更改了同一行,但以不同方式更改了 。 (请记住,所有三个哈希值必须不同,因此Git将diff PB PL
中的一组更改与diff PB PR
中的更改结合起来。)
最明显的情况发生在一方(让我们先选择左侧)说:
unchanged context
-changed line
+replacement 1
more unchanged context
和另一个说:
unchanged context
-changed line
+replacement 2
more unchanged context
这里删除一行或多行,而是插入一行或多行,但插入的行不匹配。在这种情况下,merge
冲突样式将其表示为:
unchanged context
<<<<<<< left-label
replacement 1
=======
replacement 2
>>>>>>> right-label
more unchanged context
diff3
上下文样式将其显示为:
unchanged context
<<<<<<< left-label
replacement 1
||||||| merged common ancestors
changed line
=======
replacement 2
>>>>>>> right-label
more unchanged context
如果我们只是添加文本,但在同一行添加不同的文本,我们也会遇到合并冲突。同样,来自每一侧的添加文本显示在冲突标记中。 (如果我们将相同的文本添加到双方 - 作为新文本,或作为更改行的替换文本,Git将获取此添加的一个副本,并且没有冲突。)
如果替换行的一个但不是两个为空 - 即,如果左侧或右侧diff读取:
unchanged context
-changed line
more unchanged context
然后缺少merge
或diff3
样式标记文件中的替换行的一个但不是两个。 (如果两个差异只是删除原始行,则没有冲突:Git删除一个。)
同样,如果一方在另一方删除的行的上方或下方添加一行,则会发生冲突。这次冲突显示保留并随后添加a的一侧具有所有线,而另一侧没有线。例如:
some merge conflict.
Line that will conflict.
+add line below it
Rest of the
VS
some merge conflict.
-Line that will conflict.
Rest of the
(如果你在上面而不是下面添加一行,也会出现同样的情况。)
这是diff3
冲突风格非常有用的地方。这是其中一种情况的整个合并文件:
We need a base file
in which to make
some merge conflict.
<<<<<<< HEAD
||||||| merged common ancestors
Line that will conflict.
=======
Change the line that will conflict.
>>>>>>> b2
Rest of the
base file for the
merge conflict example.
请注意,它现在显而易见 - 或者至少是神秘 - 在基本版本中有一行读取Line that will conflict.
,我完全删除了左侧HEAD
版本,并替换为右侧b2
版本中的其他行。