I'm seeing a weird merge-failure in Git following a "squashed" merge-to-master.
I've created a tiny GitHub repo to reproduce the issue.
Essentially, the process is as follows:
merge --squash
'd these commits into master.What's going on here? Why doesn't the merge from master back into the branch include the change made directly to the master branch? Is this a bug or a use-error?
This is not a bug. The problem is that your squash commit is not a merge, so git doesn't know that it is connected to Branch-1
. It sees it as an ordinary commit. When you merge master
into Branch-1
, git sees that there were following changes since those branches diverged:
master
: added file1
and file2
, then deleted file1
. Overall diff: added file2
.Branch-1
: added file1
, added file2
. Overall diff: added file1
and file2
.Git merges branches using those overall diffs. You added file2
in both branches, but there is no merge conflict, because file2
s from both branches are identical. So the outcome of the merge is a commit, containing both file1
and file2
.
For the same reason your pull request will add file1
to master
.
But if you've done a real merge instead of a squash, the result would be as you expect.
Actually, this is even mentioned in 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.