奇怪的 git 合并?

Jho*_*per 1 git git-merge git-merge-conflict

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

我正准备与其他 1 位朋友开始一个项目,我们决定使用 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 行,我在两个分支的预创建行上放置了 Test(此处为数字),对于朋友分支,我创建了第 2 行和第 3 行,并放置了 Hotfix 和第 3 行。

tor*_*rek 5

Git 认为,如果更改对同一原始源代码行进行不同更改,或者如果这两个更改在边缘“接触”,则更改会相互冲突。究其原因,后者则是Git不会知道什么是为了把他们进来。

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

+Test 1
Run Code Online (Sandbox Code Playgroud)

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

+Test 2
+Hotfix
Run Code Online (Sandbox Code Playgroud)

Git 不知道是先把你的行放在他的两行之后,还是先把他的两行放在你的行之后。

你说他确实改变了“第 3 行”。没有第 3 行。也许原来所谓的空文件实际上是一个行?那么你的改变是:

-
+Test 1
Run Code Online (Sandbox Code Playgroud)

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

+Test 2

+Hotfix
Run Code Online (Sandbox Code Playgroud)

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

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

This test file
has several
lines in it.
Run Code Online (Sandbox Code Playgroud)

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

Test 1
This test file
has several
lines in it.
Test 2
Hotfix
Run Code Online (Sandbox Code Playgroud)

考虑合并基础

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

请记住,每次提交都会存储每个文件的完整快照。所以,如果可以的Git发现任何承诺,你你开始工作之前有,任何文件,我们想知道一下,Git有在提交文件的一些副本。

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

当这些更改影响不同的行并且不相邻时,Git 可以自行组合它们。当它们影响相同的行或确实相邻时,Git 不能单独将它们组合起来。