Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git - diff3 Conflict Style - Temporary merge branch

I am doing a merge with merge.conflictStyle set to diff3. Normally, this inserts three (3) sections separated by four (4) sets of characters.

The Git Documentation for Merge clearly explains what these symbols mean for a simple case (as described below).

Regular diff3:

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

However, I am getting a more complicated result with numerous extra lines (see below). I have a feeling that has something to do with the fact that I made numerous merges in the ancestors of the commits that I am currently merging, but I cannot figure out what the extra lines mean. I also cannot seem to find any documentation for this behavior.

Here is what I got (edited of course, to protect the identity of the code).

(There are no conflict markers in the code of any of the commits I am trying to merge, so that is not the answer.)

<<<<<<< ours
||||||| base
<<<<<<< Temporary merge branch 1
||||||| merged common ancestors
        if (sendRedirect(result))
            return new Result("redirect");

=======

        if ( result.getId() != null )
        {   
            object = new SomeObject(searchResult.getId()) ;
        }

        if (sendRedirect(result)){
            return new Result("redirect");
        }

>>>>>>> Temporary merge branch 2
=======

        if ( result.getId() != null )
        {   
            object = new SomeObject(searchResult.getId()) ;
        }

>>>>>>> theirs

I believe that this question is asking the same thing, but the answer does not explain anything other that it has something to do with diff3, which the questioner already indicated in the Title as being something he/she is familiar with. I tried editing that question twice, but got rejected, so I am asking it again.

like image 481
Joseph K. Strauss Avatar asked Jul 13 '15 20:07

Joseph K. Strauss


1 Answers

What you have here (with the Temporary merge branch 1 and same with 2) is due to git's "recursive merge" method:

            o->branch1 = "Temporary merge branch 1";
            o->branch2 = "Temporary merge branch 2";
            merge_recursive(o, merged_common_ancestors, iter->item,
                            NULL, &merged_common_ancestors);

(merge-recursive.c, around line 1940). Git will do a recursive merge when the commit graph has multiple candidates for the merge-base (see this blog post for more). To (over?)simplify a bit, git has done an internal, recursive merge that produced a merge conflict, then done the outer merge and hit another merge conflict. What you see is the outer merge conflict (ours vs theirs) with the inner conflict shown as the "base" version.

You may find that you get better results by choosing some other merge strategy, or using an alternative diff algorithm (the patience, minimal, and histogram algorithms vs the default myers). Or, you might want to disable diff3 style for a bit, so that you simply don't see the inner merge.

like image 161
torek Avatar answered Nov 15 '22 06:11

torek