与 git 合并的奇数?

Oddness with git merges?

我是 git 的新手,所以这对其他人来说可能看起来很简单,我就是不明白。

我正准备与另外 1 位朋友一起开始一个项目,我们决定使用 git 作为我们的版本控制系统,因此我们已经 运行 进行了测试以了解如何这行得通。以下是我们迄今为止测试过的内容以及我们遇到问题的地方:

我们有3家分店

好的,所以:

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

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

我认为这无关紧要,但我们已经在 Bash CLI 中针对 windows、Bash 直接在 Linux、Github 桌面版、Gitkraken 和 Gmaster,结果相同。

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

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

Git 认为如果对同一原始源代码行进行不同的更改,则更改会相互冲突 如果这两个更改 "touch"边缘。后者的原因是Git不知道order把它们放进去

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

+Test 1

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

+Test 2
+Hotfix

Git不知道是先放你的行后放他的两行,还是先放他的两行后放你的行

虽然你说他所做的事情改变了 "line 3"。没有第 3 行。也许原来的空文件实际上是 blank 行?那么你的变化是:

-
+Test 1

去掉空行,放入Test 1行。 他的现在的变化是:

+Test 2

+Hotfix

(即保留空行,但添加第一行和第三行)。这个改动是冲突的,因为你改了空行而他保留了它,或者——如果我们换个角度看这个——他在空行上下加了一行,而你改了空行。 (Git 不查看 changed 行,而只查看 added and/or deleted 行,这是另一个改变邻接——像这样在边缘接触——冲突的原因。)

无论哪种方式,如果您更改了彼此不同或 "touch" 不同的行,就不会发生合并冲突。也就是说,假设原始 text.text 文件读取:

This test file
has several
lines in it.

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

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

想想合并基地

另一种表述方式是:Git 没有将他的更改添加到文件的 您的版本。 Git 也没有将您的更改添加到文件的 他版本 中。 Git 正在查找文件的 merge base 版本。

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

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

当这些变化影响不同的线路且不相邻时,Git可以将它们自行组合。当它们影响相同的线路或相邻时,Git 不能单独组合它们。