首页 > 解决方案 > git合并的奇怪之处?

问题描述

我是 git 新手,所以这对其他人来说似乎很简单,我只是不明白。

我正准备和另外一位朋友开始一个项目,我们决定使用 git 作为我们的版本控制系统,所以我们一直在运行测试,看看它是如何工作的。以下是我们迄今为止测试过的内容以及我们遇到问题的地方:

我们有3个分店

可以,然后呢:

  1. 在创建其他 2 个分支之前,我直接在 master 中创建了一个 test.txt 文件,并将 txt 留空。
  2. 我们创建了其他 2 个分支,我在第 1 行签出我的分支,在没有其他行的情况下写入“Test 1”,然后提交并将其与 master 合并。
  3. 我的朋友检查了他的分支并在第 1 行写了“Test 2”,在第 3 行写了“Hotfix”,然后他提交并与 master 合并并得到一个合并错误,因为 1 在第 1 行更改为 2,并且因为 Hotfix加入。

与我们正在运行的测试相比,这有点简化,但是 git 真的不够聪明,无法在进行如此简单的更改时识别出差异吗?我可以看到它询问第 1 行是否应该有 1 或 2 但为什么它抱怨在新行上添加了修补程序?

我认为这并不重要,但我们已经在 Windows 的 Bash CLI、Linux 中的 Bash、桌面版的 Github、Gitkraken 和 Gmaster 中尝试了相同的测试,结果都相同。

编辑,为了清楚起见,这里读出了我在终端中所做的事情:我解释了我在提交消息中所做的事情,虽然我不知道如何从 bash 终端显示合并冲突,但这里是冲突的屏幕截图它在 vscode 中打印:https ://imgur.com/a/Yd6EXx2 。

此外,为了更清楚起见,当创建 .txt 时,有 1 行,我将测试(此处的数字)放在两个分支中预先创建的行上,对于朋友分支,我创建了第 2 行和第 3 行,并将 Hotfix 和第 3 行。

标签: gitgit-mergegit-merge-conflict

解决方案


Git 认为,如果更改对同一原始源代码行进行不同的更改,或者如果两个更改“接触”边缘,则更改会相互冲突。后者的原因是 Git 不知道将它们放在什么顺序。

也就是说,假设从同一个空test.txt文件开始,您的更改是:

+Test 1

(即加一行阅读Test 1),他的变化是:

+Test 2
+Hotfix

Git 不知道是先放你的一行,然后是他的两行,还是先放他的两行,然后再放你的一行。

您说他所做的某件事改变了“第 3 行”。没有第 3 行。也许最初的所谓空文件实际上是一个行?那么你的改变是:

-
+Test 1

也就是说,删除空行并放入行 reading Test 1现在的变化是:

+Test 2

+Hotfix

(即保留空行,但添加第一行和第三行)。此更改冲突,因为您更改了空白行而他保留了它,或者 - 如果我们稍微不同地看待这一点 - 他在空白行的上方和下方添加了一行,而您更改了空白行。(Git 不查看更改的行,而只查看添加和/或删除的行,这就是为什么相邻的更改 - 像这样接触边缘 - 冲突的另一个原因。)

无论哪种方式,如果您更改了不同的行或没有“接触”彼此的行,您都不会遇到合并冲突。也就是说,假设原始text.text文件读取:

This test file
has several
lines in it.

您进行了添加Test 1顶部的更改。他做了一个改变,在底部增加了Test 2和。Hotfix当 Git 将你们开始的文件的版本(三行)与您的版本(四行)和他的版本(五行)进行比较时,Git 发现您的更改是在“第 0 行”(顶部文件)和第 1 行,他的更改是在第 3 行之后插入“第 4 行”(文件底部)之前。这些更改重叠,因此 Git 可以将这两个更改应用到原始的三行文件,并得出一个六行文件:

Test 1
This test file
has several
lines in it.
Test 2
Hotfix

考虑合并基础

另一种说法是:Git 不会将他的更改添加到的文件版本中。Git 也不会将您的更改添加到的文件版本中。Git 正在查找文件的合并基本版本。

请记住,每次提交都会存储每个文件的完整、完整的快照。因此,如果 Git 可以找到你们开始工作之前的任何提交,无论我们想知道什么文件,Git 都会在该提交中拥有该文件的一些副本。

合并基础是你们俩开始的“最佳”提交——最接近你们俩最终的提交。由于你们都是从同一个提交开始的,所以你们都有这个文件的相同版本。因此,Git 可以运行两个git diff操作。一个发现改变了什么。另一个发现改变了什么。Git 的工作是组合这两组更改,并将这些组合更改应用到基本副本。

当这些更改影响不同的行并且不相邻时,Git 可以自行组合它们。当它们影响相同的行或确实邻接时,Git 无法自行组合它们。


推荐阅读