[PATCH] add support for marking changesets as dead

Matt Mackall mpm at selenic.com
Thu Feb 3 11:02:09 CST 2011

On Thu, 2011-02-03 at 12:01 +0100, Martin Geisler wrote:
> Matt Mackall <mpm at selenic.com> writes:
> > Ideally, if we're using both concepts together, people will only ever
> > regularly abandon changesets that are still in the liquid state. In
> > other words 'freezing' should be interpreted as a promise not to later
> > 'abandon' a changeset.
> >
> > A picture might be helpful here:
> >
> >         |          |
> > frozen  1  liquid  2  abandoned
> >         |          |
> >
> > (Ancestors are on the left, descendants are on the right)
> I talked briefly with marmoute on IRC about how the boundaries move and
> we are both confused.
> If we assume that Alice and Bob both have the same changesets, but
> boundary 2 differs in their two repositories. How do they know who is
> right?
> If Alice moved the boundary to the left in order to abandon some
> changesets and the does a 'hg push' to Bob, then how do we know that
> Bob's changesets should be abandoned too?

> The problem is that it could just as well have been Bob that had moved
> the boundary to the right.
> Alice:
>        |               |
>   [A] -1- [B] --- [C] -2- [D]
>        |               |
> Bob:
>        |       |
>   [A] -1- [B] -|- [C] --- [D]
>        |       |
> what to do?
> This issue does not come up when one adds extra changesets to the
> history since there is a clear distinction between the two cases.

Good question. We do in fact have the same issue with bookmarks right
now. Bookmarks want to move forward, and if Alice tries to push bookmark
X that points to a descendant of Bob's bookmark X, it will succeed even
if the actual change was that Bob moved X backwards.

We also have a similar issue with tags. Two users can simultaneously
modify a tag and move it forward or backward. The tags logic has some
very interesting magic to decide which tags supersede each other that we
probably don't want to duplicate.

And we also have a similar case that I laid out as case A/case B in my
first message. In short, whenever we have people making simultaneous
changes, we have a potential for conflicts. How much work we want to
expend on doing the right thing here isn't clear. For instance, I don't
think we're going to worry ourselves too much about people trying to
make bookmarks go backwards.

Let me take a moment to point something out that's not immediately
obvious: if your dead head changesets are always invisible leaf nodes,
then implementing them with their original semantics via pushkeys
instead is straightforward: simply translate every dead head node that's
a child of <node> into a deadx=<node> key. Then when you pull, if you
have <node>, you pull the deadx key pair as well. And if you push
<node>, you push the key. And you treat this set as append-only.

In other words, if you can visualize a solution that works by adding
additional nodes to the real DAG's periphery, it can fairly easily be
translated to pushkey without add magic to the DAG itself. And since
pushkeys are NOT append-only, they're actually more flexible.

Now back to your example above. We've got two cases, Bob moves left,
Alice moves right. Here's a proposed approach: first, pick a preferred
direction. Then, if you move a key in this direction, you simply update
it. Going in the other direction, you keep the previous key and add a
new key to override it. So, for instance, let's say we prefer moving

Case 1: Bob moves left
Bob starts with deadx = D. Bob adds deady = C, pushes it to Alice. Since
she's now got deadx and deady, C:: (= C:: && D::) is dead.

Case 2: Alice move right
Alice starts with deadx = C. She changes it to deadx = D, pushes it to
Bob. Bob now only has deadx = D, so only D:: is dead.

Again, not sure it's worth the trouble, but this sort of thing is

Mathematics is the supreme nostalgia of our time.

More information about the Mercurial-devel mailing list