It recently came to my attention that not everyone overrides the
merge.conflictStyle git-config setting. So in case anyone
here wanted to try something new out that would provide more context
during a Git conflict resolution scenario here you go.
diff3 which you can set like this to override the default:
git config --global merge.conflictStyle diff3
When rebasing you will get the following markers:
<<<<<<< HEAD THIS IS SOME CODE ||||||| merged common ancestors This is some code ======= This is some other code >>>>>>> d5439077.....
Notice the new section from the default version between
====== which denotes the state that the rebased commit expected to
The meaning of the diff between
remains what it used to be in the two way diff output which is the
code on the branch you are rebasing on top of and the content between
>>>>>>> is what you want to record on top of the
HEAD of the rebase branch.
A simple illustration
My last merge conflict arose when attempting to apply an old stash to the latest HEAD of new branch off of our mainline. It was a Nix expression conflict and looked like the following:
<<<<<<< Updated upstream ruby = self.ruby_2_5; ||||||| merged common ancestors nodejs = nodejs_10_22_1; ruby = self.ruby_2_5; ======= nodejs = nodejs_10_22_1; #ruby = self.ruby_2_5; >>>>>>> Stashed changes
What this is saying is that the current upstream has the following at that location of the file:
ruby = self.ruby_2_5;
When this commit was applied last that part of the upstream content looked like this:
nodejs = nodejs_10_22_1; ruby = self.ruby_2_4;
My changes has content at that region of the file that looks like this now:
nodejs = nodejs_10_22_1; #ruby = self.ruby_2_5;
What this is saying is that another change to the upstream branch has
removed (or moved) the
nodejs version pinning, so maybe I should
discard it (of course context matters given how Git works).
Ignoring the first line of the region around our change means we just need to decide how to resolve the line that contains the change:
<<<<<<< Updated upstream ruby = self.ruby_2_4; ======= #ruby = self.ruby_2_5; <<<<<<< Stashed changes
The added context of the middle section allowed me to understand what was not relevant for resolution which we could not have confidently deduced from just a two way merge conflict context (only the top and the bottom parts of the diff above).
My resulting change was to delete the entirety of the conflict because I had merely commented out a line of Nix which means we could just delete it to get the same effect. It is also a great illustration of why commented out unused code, even just to "try" something (assuming you have the previous version in Git) hinders effectiveness and I should feel bad for this. I do! :)
Even in a simple example, we found having this extra context in the merge conflict beneficial since it allowed us to understand what part of the conflict was relevant to resolve.
Hopefully that provided a quick illustration of how to improve effectiveness of resolving merge conflicts, even in a minimally beneficial case.