Search code examples
gitdiffgit-configdiff3

How do I use "zealous diff3" with git? And what are the pros and cons?


I just read the release notes for Git 2.35.0 (note 2.35.1 is already available though).

In those release notes, I saw that:

  • "Zealous diff3" style of merge conflict presentation has been added.

My questions:

  1. How do I make git diff / difftool default to "zealous " diff presentation?
  2. What are the pros and cons of using it over the default diff presentation mode?

Solution

  • The new "zealous diff3" style is:

    merge.conflictStyle = zdiff3
    

    which you'd set with:

    git config --global merge.conflictStyle zdiff3
    

    for instance (assuming you want this in your per-user configuration).

    The default style is merge:

    Here are lines that are either unchanged from the common
    ancestor, or cleanly resolved because only one side changed,
    or cleanly resolved because both sides changed the same way.
    <<<<<<< yours:sample.txt
    Conflict resolution is hard;
    let's go shopping.
    =======
    Git makes conflict resolution easy.
    >>>>>>> theirs:sample.txt
    And here is another line that is cleanly resolved or unmodified.
    

    (this example is straight from the git merge documentation). The diff3 style adds the merge base version in the middle, with vertical bars:

    Here are lines that are either unchanged from the common
    ancestor, or cleanly resolved because only one side changed,
    <<<<<<< yours:sample.txt
    or cleanly resolved because both sides changed the same way.
    Conflict resolution is hard;
    let's go shopping.
    ||||||| base:sample.txt
    or cleanly resolved because both sides changed identically.
    Conflict resolution is hard.
    =======
    or cleanly resolved because both sides changed the same way.
    Git makes conflict resolution easy.
    >>>>>>> theirs:sample.txt
    And here is another line that is cleanly resolved or unmodified.
    

    Note that in order to show the difference between the base version and both branch-tip versions, the line:

    or cleanly resolved because both sides changed the same way.
    

    which used to be outside the <<<<<<< ... >>>>>>> section (because it was cleanly resolved) is now inside this section.

    What zdiff3 does is take the same "or cleanly resolved" path that merge takes:

    Here are lines that are either unchanged from the common
    ancestor, or cleanly resolved because only one side changed,
    or cleanly resolved because both sides changed the same way.
    <<<<<<< yours:sample.txt
    Conflict resolution is hard;
    let's go shopping.
    ||||||| base:sample.txt
    or cleanly resolved because both sides changed identically.
    Conflict resolution is hard.
    =======
    Git makes conflict resolution easy.
    >>>>>>> theirs:sample.txt
    And here is another line that is cleanly resolved or unmodified.
    

    This is a lie, of sorts, but it's a useful lie.

    Note that if you'd like, you can take any existing conflicted file and re-create the conflict in a new merge style:

    git checkout --conflict=zdiff3 conflicted.txt
    

    (or the same with git restore but I haven't retrained my fingers yet 😀). Be careful with this as it overwrites any attempt you've made at merging.