为什么 Git 没有给我任何冲突?

7

我发现了一个奇怪的问题。我正在测试一个git repo,发现出现了以下情况。

我创建了一个简单的git repo,并添加了一个包含以下内容的文本文件。

Hello Git..!

First Line

作为初始提交进行了提交。

然后我从该提交创建了一个名为“abc”的分支,并将文件的内容更改为以下内容。

(abc) -> 分支

Hello Git..!

First Line
Second Line

已提交。然后我切换回我的主分支并将文件内容更改如下。

(master) -> 分支

Hi Git..!

First Line

已提交。然后我尝试将“abc”分支合并到“master”分支。我认为这将会产生冲突,但它通过递归成功地合并到以下位置。

Hi Git..!

First Line
Second Line

为什么没有显示冲突?我尝试了几次,有时候如果像下面这样没有空行,就会出现这种情况。
Hello Git...!
First Line

如果显示冲突,那么就说明存在冲突。我不理解这个。请有人帮助我理解。

我尽可能地搜索了很多内容,但我找不到一个问题或答案来解决我的问题。

我已经将样例上传到GitHub。如果有人克隆它并尝试合并,就可以重现它。

https://github.com/Ranjith-Suranga/test-repo

有没有办法强制GIT显示冲突?我知道这是一个奇怪的问题,没有人需要出现冲突。但我也不喜欢这种情况发生。想象一下,这发生在我的真实代码中。

更新


由于大部分评论和答案都表示不可能出现这种冲突,所以我不得不更新这个答案。

好的,让我们再次执行上述所有步骤,删除第二个空行。

我们开始吧,

  1. 我创建了一个简单的git repo,并添加了一个文本文件,其内容如下。这次前两行之间没有空行。
Hello Git..!
First Line

作为初始提交进行了提交。

  1. 然后我从该提交创建了另一个名为“abc”的分支,并将文件的内容更改为下面的内容。(再次删除空行)

(abc) -> 分支

Hello Git..!
First Line
Second Line

已提交。

  1. 然后,我检出回到我的主分支,并将文件内容更改为以下内容。

(master) -> 分支

Hi Git..!
First Line

已提交。

  1. 然后我尝试将"abc"分支合并到"master"分支。这一次它会告诉我有合并冲突

如果你不相信我,这是一个样例的Github库 https://github.com/Ranjith-Suranga/test-repo2

第一个没有任何冲突,第二个几乎相同,除了移除的空行,它会有冲突。 但问题是为什么?


4
为什么会出现冲突?你在两个分支上更改了两行不同的代码。只有当你在不同的分支上修改了相同的代码行(或代码行范围)并尝试合并时,Git 才会给出冲突提示。 - Tyler Marshall
@TylerMarshall 请查看更新后的问题。 - Ranjith Suranga
我已经给你的更新步骤添加了数字,这样更容易参考每一个步骤。 - Caleb
5个回答

1
请注意,您的文件的所有版本都包含一个不完整的最后一行。当您添加另一行时,这意味着您不仅要添加一行,而且还要删除不完整的行,然后添加两行。
在第二次尝试中,当您合并两个分支时,Git检测到相邻文本块中的更改。与您可能想的相反,此行读取
First Line

实际上,由于在一个分支中添加的最后一行换行符被视为该行的修改,因此它并没有保持不变。由于来自不同分支的相邻行有修改,Git 报告了合并冲突。

在您的第一次尝试中,在读取First Line的行上方留出空白行。这行作为锚点,在合并期间保持稳定。它允许 Git 将来自不同分支的更改清晰地分离成不同的文本块。因此,Git 可以自动整合修改,避免冲突。


0
据我所知,在这种情况下不会发生合并冲突,因为这里没有冲突,所以假设你有4行和2个分支。
案例1:在第一个分支中修改Line(1),在第二个分支中修改Line(1)和Line(2),这不是冲突。
案例2:在第一个分支中修改Line(1),在第二个分支中仅修改Line(1)(您完全修改了相同的行),这是合并冲突。
自己尝试一下,您会注意到区别。

@MAHFOUDHKERBOUDCHE 感谢您回答我的问题,但我认为我没有找到我正在寻找的正确答案,请查看更新后的问题,如果您能帮忙解答,谢谢。 - Ranjith Suranga

0
为什么它没有显示任何冲突?
可能是因为您在 master 分支中的更改与 abc 分支中的更改完全相同,直到 "First Line" 行的结尾。因此,没有冲突的更改。如果您在文件的第三行中将其更改为 "Third Line" ,那么您将具有两个不同更改的提交,在同一行上,这将导致冲突。但如果更改是相同的,则没有问题。
我尝试了几次,有时如果像下面这样没有空行......就会显示冲突。
当然。现在您已将 master 中的第二行更改为 "First Line" ,第三行更改为空白,而 abc 则具有在第二行和第三行上有所不同的提交。Git 应该选择哪一个?无法确定,因此您必须解决它。在前面的情况下,Git 不必选择两种选项,因为它们都是相同的。
更新:
在您的更新的第一步中,您已经创建了一个包含以下内容的初始提交文件:
Hello Git..!
First Line

这是在 master 分支中。然后你创建一个新的 abc 分支,添加一行代码。在第三步中,你切换到了 master 分支并修改了文件。

Hello Git..!
First Line

并提交了那个。但这正是一开始应该在master中的内容,所以不清楚你提交了什么更改。听起来你在master中有另一个更改文件的提交,或者可能是一些杂乱的空格字符。

归根结底,当合并两个文件时,git无法确定如何处理时,会告诉你存在合并冲突。发生这种情况时,它会用>>>>>=====<<<<<指示符标记文件和更改区域的两个版本,因此您应该能够准确地看到冲突的位置。不同版本的git甚至在自动解决问题方面可能会表现出不同的行为,或者原因不同。

回顾您最初的示例以及您链接的Github存储库,很容易看出为什么没有冲突:在master中第二次提交和abc中的第二次提交影响了不同的行,您可以在Github上看到它。这是master中提交549009d的更改:

commit 549009d

这显然替换了文件的第一行。这是分支abc中提交的462394b:

commit 462394b

正如您所看到的,这个更改并没有涉及第一行,只影响了第三行(并添加了第四行)。因此,这些更改是完全独立的,git 可以毫不含糊地同时应用它们。


0
答案是因为你在分支abc上修改了“第一行”,而git无法将其匹配回主分支上的“第一行”。你所做的更改是在行末添加了一个换行符(如此处所示)。
请再试一次,但使用以换行符结尾的初始README。

Git认为你已经将“第一行”更改为“第二行”,因为缺少匹配的换行符。它还认为你插入了一个新行,内容为“第一行”。 - Tyler Marshall
再次感谢您的回答。但是,如果是这种情况,那么我的第一个存储库中也有同样的问题。请参见此处。为什么它不显示任何冲突呢? - Ranjith Suranga
在您的第一个 Repo 中,Git 将一个分支中的空白行与另一个分支匹配。而在第二个 Repo 中,由于换行符的关系,根本没有要匹配的行,这导致了冲突。 - Tyler Marshall
对于第一个仓库,你可以将空行看作是一个障碍。Git 知道主分支上方发生了更改以及分支 abc 下方发生的更改。合并两个分支意味着从主分支中取出空行以上的更改和从分支 abc 中取出空行以下的更改。空行并没有什么特别之处。如果 第二个仓库的 README 总是以换行符结束,则也不会出现合并冲突。 - Tyler Marshall

-1

当不同的用户推送提交到存储库时,Git会创建冲突。如果您使用相同的用户创建冲突,则这些冲突将永远不会出现。


我不认为这是真的。我可以自己制造冲突,不需要任何人的帮助。 - evolutionxbox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接