Git - diff3 Conflict Style - Temporary merge branch
Asked Answered
G

1

31

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.

Gavette answered 13/7, 2015 at 20:10 Comment(4)
Off the top of my head I would say it looks like someone at some point in the past committed a file that still had merge conflicts tagged in it. Thus, those merge markers are now considered part of the actual file in one parent or the other in the current merge...Universality
@Universality I indicated in the question that this is not the case.Gavette
Sorry, I took a literal interpretation of "There are no conflicts in the code of any of the commits I am trying to merge", which does not preclude that there might have been some in the branch that you are trying to merge into...Universality
Just ran into this issue (Hi Kalman). I was merging a branch that contained a merge, that already had a resolved conflict resolution. The weird thing is that there were no more changes to be merged, but git decided it needed to merge. I had all my resolutions saved in rerere so i just redid the merges as one.Kraigkrait
O
24

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.

Organon answered 13/7, 2015 at 20:41 Comment(4)
So, you have to basically read it as if some of it is nested? I guess it would help to indent some of the symbols to visualize it. Also, is there anywhere to read up on this?Gavette
Yes (to the nested part); as for reading up on it, see that blog posting (that was the best I could find in a quick search - it's specifically for ClearCase but the idea is the same).Organon
Thanks for your guidance. But when I try to use the 'patience' strategy, I get the message, "Available strategies are: octopus ours recursive resolve subtree." Are those different names for the strategies you listed? Do I need to install something, I wonder?Classicize
@Sean: Those aren't strategies, they are -X arguments (what I like to call "eXtended options"). You would use git merge -X patience ..., for instance, to pass the extended "patience" option to your chosen strategy.Organon

© 2022 - 2024 — McMap. All rights reserved.