(1) How to detect criss-cross (2) is ancestor(*changeset) always the "base" of merges

Matt Mackall mpm at selenic.com
Tue Dec 31 21:51:33 UTC 2013


[resending]

On Sun, 2013-12-29 at 22:53 +0100, Giovanni Gherdovich wrote:
> Hello,
> 
> I'll use a few names that I'm not sure are universal,
> so my definitions:
> 
> LCA (Lowest Common Ancestor) of nodes X,Y:
>      a common ancestor A of X and Y such that
>      no descendant of A is also a common ancestor of X and Y.
>      As far as I understand, LCA(X,Y) is chosen as "base" when
>      performing 3-way merge.
> 
> Criss-Cross merge: when one wants to merge D and E but
>      LCA(D,E) is not unique, the situation is called "criss-cross
merge".
>      As in the picture below (please monospaced fonts), where history
>      flows from top to bottom, it can happen when developers
>      pull from each other and then merge back together.
> 
>    A
>   / \
>  B   C
>  |\ /|
>  | X |
>  |/ \|
>  D   E
>   \ /
>    F
> 
> 
> Questions:
>    (1) people FUD-y thinks that "criss-crossing" implies "troubles
ahead".
>        Well, I do. My (poor) intuition is that whatever "base" I
choose
>        it isn't gonna be... "the best", so I am gonna observe more
conflicts
>        than "necessary".
>        ----> Is this "fear" of criss-crossing justified?

The 'extra conflicts' problem is pretty minor.

The real problem is if one of the criss-crosses contains a backout or
something else that contradicts the other side. Another common case is
exec-bit flip. Then you can end up in a situation where each successive
merge _silently alternates_ whether that change is included, depending
on which merge ancestor is chosen. Each individual merge will be
'locally correct' given the information it uses, but taking in the
bigger picture of the other possible merge histories, there ought to be
a conflict.

So, yes, there are non-trivial problems that can result from criss-cross
flows that you ought to be wary of. 

>              Are they really a Bad Thing that you should try to avoid
in
> your workflow?

Eliminating them categorically eliminates an especially confusing class
of merge problems. If you think confusing merge problems are a Bad
Thing, then yes, you should probably avoid them in your workflow.

>        Beware, I am not trolling about recursive merging[1] (git's
> strategy) or
>        consensus merge[2], I have read the reference below.
>        [1]
http://selenic.com/pipermail/mercurial/2012-January/041456.html(Matt
> on Recursive Merge Strategy)
>        [2] http://mercurial.selenic.com/wiki/ConsensusMerge
> 
>    (2) Is there a way to use revset queries in order to detect if a
merge
> is gonna be criss-cross?
>        Or some other way to build a criss-cross detector that isn't
too
> hard to implement.

This will list all the candidate merge ancestors. If there's more than
one, you're in criss-cross territory:

hg log -r 'heads(::x and ::y)'

>    (3) How to ask mercurial "what is the 'base' you will use for this
> merge" ?
>        The "ancestor(*changeset)" revset function gives the "Greatest
> common ancestor of the changesets",
>        is that function wired to the very same algorithm that selects
> "base" in a merge?

Yep.

-- 
Mathematics is the supreme nostalgia of our time.

-- 
Mathematics is the supreme nostalgia of our time.





More information about the Mercurial mailing list