Git 错误的无操作合并
Git erroneous no-op merge
在 "squashed" 合并到主控之后,我在 Git 中看到奇怪的合并失败。
我创建了一个 tiny GitHub repo 来重现这个问题。
本质上,流程如下:
- 我创建了两个分支。
- 在一个分支中,我做了two commits。
- 我将这些提交合并到第二个分支中。
- 我
merge --squash
'd these commits into master.
- 我deleted a file directly on the master branch.
- 然后我merged the changes in master back into the original branch。
- 这就是问题所在。此合并不会对分支产生 无更改。 master上删除的文件还在。
- 我将这个最新分支上的所有内容都拉到了第二个分支中。
- 我开了一个pull request来演示将第二个分支合并到master会重新引入之前删除的文件
这是怎么回事?为什么从 master 合并回分支不包括直接对 master 分支所做的更改?这是错误还是使用错误?
这不是错误。问题是你的 squash commit 不是合并,所以 git 不知道它连接到 Branch-1
。它将其视为普通提交。当您将 master
合并到 Branch-1
时,git 发现自从这些分支发生分歧后发生了以下变化:
- 在
master
中:添加了file1
和file2
,然后删除了file1
。总体差异:添加 file2
.
- 在
Branch-1
中:添加了 file1
,添加了 file2
。总体差异:添加了 file1
和 file2
.
Git 使用这些整体差异合并分支。您在两个分支中都添加了 file2
,但没有合并冲突,因为两个分支中的 file2
是相同的。所以合并的结果是一个提交,包含 file1
和 file2
.
出于同样的原因,您的拉取请求会将 file1
添加到 master
。
但是,如果您进行的是真正的合并而不是压缩,结果就会如您所愿。
其实这个在git help merge里面也有提到:
With the strategies that use 3-way merge (including the default, recursive), if a change is made on both branches, but later reverted on one of the branches, that change will be present in the merged result; some people find this behavior confusing. It occurs because only the heads and the merge base are considered when performing a merge, not the individual commits. The merge algorithm therefore considers the reverted change as no change at all, and substitutes the changed version instead.
在 "squashed" 合并到主控之后,我在 Git 中看到奇怪的合并失败。
我创建了一个 tiny GitHub repo 来重现这个问题。
本质上,流程如下:
- 我创建了两个分支。
- 在一个分支中,我做了two commits。
- 我将这些提交合并到第二个分支中。
- 我
merge --squash
'd these commits into master. - 我deleted a file directly on the master branch.
- 然后我merged the changes in master back into the original branch。
- 这就是问题所在。此合并不会对分支产生 无更改。 master上删除的文件还在。
- 我将这个最新分支上的所有内容都拉到了第二个分支中。
- 我开了一个pull request来演示将第二个分支合并到master会重新引入之前删除的文件
这是怎么回事?为什么从 master 合并回分支不包括直接对 master 分支所做的更改?这是错误还是使用错误?
这不是错误。问题是你的 squash commit 不是合并,所以 git 不知道它连接到 Branch-1
。它将其视为普通提交。当您将 master
合并到 Branch-1
时,git 发现自从这些分支发生分歧后发生了以下变化:
- 在
master
中:添加了file1
和file2
,然后删除了file1
。总体差异:添加file2
. - 在
Branch-1
中:添加了file1
,添加了file2
。总体差异:添加了file1
和file2
.
Git 使用这些整体差异合并分支。您在两个分支中都添加了 file2
,但没有合并冲突,因为两个分支中的 file2
是相同的。所以合并的结果是一个提交,包含 file1
和 file2
.
出于同样的原因,您的拉取请求会将 file1
添加到 master
。
但是,如果您进行的是真正的合并而不是压缩,结果就会如您所愿。
其实这个在git help merge里面也有提到:
With the strategies that use 3-way merge (including the default, recursive), if a change is made on both branches, but later reverted on one of the branches, that change will be present in the merged result; some people find this behavior confusing. It occurs because only the heads and the merge base are considered when performing a merge, not the individual commits. The merge algorithm therefore considers the reverted change as no change at all, and substitutes the changed version instead.