Reducing merge headaches: git meets diff3

git has an option to display merge conflicts in diff3 format (by default it only displays the two files to be merged). You can enable it like so:

$ git config --global merge.conflictstyle diff3

Now, when you have to resolve merge conflicts, git shows your side, the side being merged, and (here's what's new) the common ancestor in between them. Here's an example of the diff3-formatted output:

cauliflower
<<<<<<< HEAD
peas
potatoes
||||||| merged common ancestors
peas
=======
>>>>>>> topic
tomatoes

Having the merge ancestor readily available helps you to quickly determine what the correct merge is, since you can infer from it the changes that were made on both sides. Here you can see that the original state was peas. On your branch potatoes was added (compare the middle section to the top) and on the other branch peas was removed (compare the middle section to the bottom). Therefore the correct change is to both add potatoes and remove peas, leaving you with just potatoes in the conflicted section.

There's really no reason you shouldn't enable the diff3 style, because you frequently need the ancestor to determine what the correct merge is.

To see that this is true, even in the simple example above, look at what the conflict looks like under the standard style:

cauliflower
<<<<<<< HEAD
peas
potatoes
=======
>>>>>>> topic
tomatoes

There's an asymmetry between peas and potatoes: one was added and one was deleted, but this merge conflict doesn't tell you anything at all about which was which! You can't determine the correct merge unless you remember the sequence of changes that led up to this point. And why should you have to rack your brain to do that? That's exactly the sort of thing that your computer can, and should, help you with.

Bonus tip: rerere (reuse recorded resolution)

If your workflow finds you redoing the same merges over and over again you might also find git's rerere (reuse recorded resolution) feature to be useful.

One of the things that is wonderful about rerere is that it provides hardly any UI surface at all. Just set it...

$ git config --global rerere.enabled 1

...and forget it. Although there is a git rerere command, you can get a lot done without using it at all.

After enabling rerere, whenever you resolve a merge conflict, git automatically squirrels away the resolution in its database. You'll see a message like this one:

$ git commit
Recorded resolution for 'soup'
[...]

And the next time you encounter the same conflict, where you would have expected git to spit out a file with conflict markers, you will instead find that it has automatically resolved the merge for you, and printed the following message:

$ git merge topic
Auto-merging soup
CONFLICT (content): Merge conflict in soup
Resolved 'soup' using previous resolution.

Just double-check to make sure nothing has gone awry, add, and commit. Save your blood, sweat, and tears for other, more interesting problems than redoing merges.

Further reading: Pro Git on rerere

24 comments:

  1. Love the diff3 format. I can't see why anyone would not want to use it. Thanks for posting!

    ReplyDelete
  2. I also love diff3. Why the heck is that not the default?

    Thanks for the tip on rerere. It sounds too good to be true.

    ReplyDelete
  3. Awesome! I did not know about the diff3 option, yet always wanted it! Can't believe I didn't look for it. Thanks for writing this up!

    ReplyDelete
  4. My two cents on why it's not the default is because it's not clear at first how it works. I mean, what "common ancestor" represents. I needed this blog to understand the concept. Thanks for that.

    ReplyDelete
  5. Look at style #3 that BitKeeper could use:
    https://www.bitkeeper.org/man/smerge.html

    That requires a bit more editing, but the information is _much_ clearer.

    ReplyDelete
  6. I really fell happy to read this post thanks for sharing this very good
    THC Diamonds

    ReplyDelete

  7. Im grateful for the article post.Really thank you! Will read on

    ReplyDelete
  8. Goodness, cool post. I’d prefer to compose like this as well – requiring significant investment and genuine difficult work to make an incredible article…

    ReplyDelete
  9. Silicon carbide and aluminium oxide are the major impregnating abrasive particles of sandpaper. sandpaper grit

    ReplyDelete
  10. thanks for your marvelous posting! I really enjoyed reading it, you happen to be a great author.

    ReplyDelete

  11. I am glad to be a visitor of this complete site! , thanks for this rare info!

    ReplyDelete
  12. Cool you write, the information is very good and interesting,

    ReplyDelete
  13. I like the helpful information that provide in articles. Keep doing it.

    ReplyDelete
  14. This blog is very informative the stuff you provide I really enjoyed reading

    ReplyDelete
  15. thank you for sharing this amazing piece of information

    ReplyDelete
  16. I do agree with all of the ideas you’ve presented in your post.

    ReplyDelete
  17. The post was really very good. Thanks for sharing.

    ReplyDelete
  18. I love seeing blog that understand the value of providing a quality resource for free.

    ReplyDelete
  19. Just the website I was looking for. It’s really awesome.

    ReplyDelete
  20. Excellent website you have here, so much cool information!

    ReplyDelete


  21. your views are in accordance with my own for the most part

    ReplyDelete

  22. I am really grateful for your blog post for giving a lot of information

    ReplyDelete