Git 错误的无操作合并

Git erroneous no-op merge

在 "squashed" 合并到主控之后,我在 Git 中看到奇怪的合并失败。

我创建了一个 tiny GitHub repo 来重现这个问题。

本质上,流程如下:

这是怎么回事?为什么从 master 合并回分支不包括直接对 master 分支所做的更改?这是错误还是使用错误?

这不是错误。问题是你的 squash commit 不是合并,所以 git 不知道它连接到 Branch-1。它将其视为普通提交。当您将 master 合并到 Branch-1 时,git 发现自从这些分支发生分歧后发生了以下变化:

  • master中:添加了file1file2,然后删除了file1。总体差异:添加 file2.
  • Branch-1 中:添加了 file1,添加了 file2。总体差异:添加了 file1file2.

Git 使用这些整体差异合并分支。您在两个分支中都添加了 file2,但没有合并冲突,因为两个分支中的 file2 是相同的。所以合并的结果是一个提交,包含 file1file2.

出于同样的原因,您的拉取请求会将 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.