gitrebase

Git rebase file content messed up


Environment:
Local machine: Linux 16.1
Repository member: Visual Studio 2022 (Win11)

Today I merged a team member’s PR into master. This member modified file B. After the PR, the master branch’s graph looked like this (simplified):

* 4c0ffef (master) Squash and merge feature-backpack
| * cdf5f1d (feature-output) Modified file A
| | * 8221882 (feature-backpack) Modified part of file B
| | * 491d131 Modified part of file B
| |/  
|/|   
* | c196bda Merge "Delete file C" (feature-output) into master
|\| 
| * 24a0b99 Deleted file C
| * a8784c7
|/
* bcd8844

After that, I use git rebase origin/master on feature-output to get the latest PR changes. However, I encountered conflicts, and I noticed that part of file A’s content was moved into file B, showing up as a conflict (while file A still existed, but with that part of its content removed).

When I tried to git rebase --abort, I found that file A’s content had permanently moved into file B. And Git marks it as a modification.

I want to know: could this be because deleting file C made Git mistakenly treat my files as renamed? But note that files A and B already existed before file C was deleted.

I once used dos2unix to unify line endings.


Solution

  • First, you used "squash and merge" on feature-backpack. Despite the name (on GitHub), "squash and merge" is not a merge. It is a rebase. As a result, the merge-base — the point at which the branch and main diverged from one another — does not change. And you can see that in your diagram. feature-backpack still has c196bda as its point of divergence from main. This is very likely to lead to merge conflicts in the future. Make it your rule to use true merges when merging from a feature branch into main.

    Second, you are now trying to rebase feature-output onto main. Its point of divergence from main is all the way back at bcd8844. The reason for this is that you already merged feature-output into main and then you did a really bad thing: you kept on using feature-output as if nothing had happened. This, too, is very likely to lead to merge conflicts.

    As for what to do now: if you are unwilling to roll everything back and do it all properly, you'll just have to merge main into feature-output (a "reverse merge") and resolve the merge conflicts really carefully.