Disable backing out merges?

Matt Mackall mpm at selenic.com
Thu Oct 6 17:26:09 CDT 2011


On Thu, 2011-10-06 at 23:51 +0200, Angel Ezquerra wrote:
> On Thu, Oct 6, 2011 at 11:03 PM, Matt Mackall <mpm at selenic.com> wrote:
> > On Thu, 2011-10-06 at 22:51 +0200, Angel Ezquerra wrote:
> >> On Thu, Oct 6, 2011 at 9:45 PM, Matt Mackall <mpm at selenic.com> wrote:
> >> > Seems a bunch of people are trying to use backout to deal with broken
> >> > merges. That doesn't work:
> >> >
> >> > - it's not well-defined what the result should be
> >> > - we can't actually erase the problematic DAG edge
> >> >
> >> > So it seems like we should just refuse to do it until we get a lot
> >> > smarter here.
> >>
> >> Say I have made a merge and pushed it. Later I realize that it is a
> >> bad merge and I want to get rid of it.
> >>
> >> If it is not possible to back it out. What are the alternatives?
> >
> > If your problem is that "I did a merge when I shouldn't have" or "I
> > should never merge branch X and Y and I did it anyway", backout doesn't
> > really help you with your biggest problem: you've introduced a merge
> > into the history graph that shouldn't be there. This bogus piece of the
> > graph will confuse future merges and the only way to truly fix it is to
> > destructively strip the bad merge from history and all clones. Backout
> > can't help you at all here, nor can anything else.
> >
> > On the other hand, if you've incorrectly performed an otherwise
> > reasonable merge, backout is still completely the wrong tool for the
> > job. Backout undoes all the changes in a changeset, which is not what's
> > wanted with a valid merge.
> >
> > So backout on a merge is ALWAYS the wrong thing.
> 
> Let's say that I don't really mind having the wrong merge on my
> history, as long as nobody bases their work on it. What is the best
> strategy in that case?

Is this the second case?

Here we have:

o-o-o-o-o-o-o-B  <- bad merge
 \           X
  o-o-o-o-o-o-G  <- good merge

Now you do a dummy merge:

o-o-o-o-o-o-o-B
 \           X \
  o-o-o-o-o-o-G-G'

Where you get into trouble is if B is ever chosen in the future as a
merge ancestor, it can -reintroduce- all the broken merge decisions. And
this can happen if anyone made commits descending from B. Consider this:

o-o-o-o-o-o-o-B-a-a-a-a-a--M2
 \           X \           /
  o-o-o-o-o-o-G-G'-o-M1-o-o
               \    /
                b--b

Now M1 was perfectly valid. But it creates a problem: there are two
reasonable choices for the common ancestor for the M2 merge: B or G.
Which one is chosen depends on which is furthest from the root. In this
case, they're equidistant. So you'll "randomly" get either a valid or
bogus merge.

What this means in practice is if you don't discover the bad merge
immediately (ie before you've even pushed it), then you've got to force
everyone to stop working and migrate all their work off the bad branch.

And again: backout is NOT the right tool here at all. Backout is
supposed to undo a changeset, by definition. And that means everything a
changeset did. And you do not want to backout an entire merge, because
then you get this:

o-o-x-xy-x  <- From bad to worse!
   \ /
    y

In other words, you just turned a broken real merge into a dummy merge,
which is probably not what you wanted.

> P.S.- Perhaps this conversation should be moved to the regular
> mercurial mailing list?

I've intentionally posted it here because this topic is not at all for
beginners.

-- 
Mathematics is the supreme nostalgia of our time.




More information about the Mercurial-devel mailing list