Why Git’s diff3
merge conflicts are confusing
It’s popular (and good!) advice to tell people to set git config --global merge.conflictStyle diff3
(“Take the pain out of git conflict resolution: use
diff3”), but I’ve always found diff3
-style merge conflicts pretty
confusing. I’ve never managed to internalize if the top section is from “my
branch” or “their branch”. It turns out there’s a reason for this — the
first section in a diff3
merge conflict is your branch in a merge, but
their branch in a rebase!
If you have feature-branch
checked out and you want to update it to the
current main
branch, here’s how you’d read a diff3
conflict:
<<<<<<< HEAD
The "current commit".
For `git rebase main`, this will be the code in `main`.
(Because `HEAD` is on top of `main`.)
For `git merge main`, this will be the code in `feature-branch`.
(Because `HEAD` is on top of `feature-branch`, and `main` is being
merged _into_ it.)
||||||| parent of ea45005
The conflicting lines before either branch changed them.
=======
For `git rebase main`, this will be the code in `feature-branch`.
(Because you're stacking the changes in `feature-branch` on top of
`main`.)
For `git merge main`, this will be the code in `main`.
(Because you're adding the changes in `main` to `feature-branch`.)
>>>>>>> ea45005
PS: Try git config --global merge.conflictStyle zdiff3
, which moves
as many lines as possible out of the merge conflict.