[PATCH] add support for marking changesets as dead

Matt Mackall mpm at selenic.com
Mon Jan 31 17:13:29 CST 2011


On Mon, 2011-01-31 at 22:41 +0100, Henrik Stuart wrote:
> On 2011-01-31 22:15, Matt Mackall wrote:
> > On Mon, 2011-01-31 at 11:10 +0100, Martin Geisler wrote:
> >> # HG changeset patch
> >> # User Henrik Stuart <hg at hstuart.dk>
> >> # Date 1295774638 -3600
> >> # Node ID 7bd977fdbca15da3c69ea7ef01df987b95475b11
> >> # Parent  0d1dca7d2a041cb1cb6c6bd90608aa87068bde02
> >> add support for marking changesets as dead
> > 
> > I like this core concept. I think we need a scheme for marking branches
> > with something like 'do not display or propagate'.
> > 
> > However, as discussed at the 1.7 sprint, I still think we should use
> > pushkey[1] to implement this. For starters, it meshes well conceptually
> > with the liquid concept that's also going to be communicated via
> > pushkey.
> 
> I think that making it a core concept rather than pushkey-based

Uh, what? Pushkey is a core concept. It's how we distribute data that's
not an immutable part of history. Since your data is all about changing
history, it should use pushkey.

>  helps
> solve a lot of usual error cases people get them into: "these heads
> aren't useful, I want them gone", "whoops, I pushed the wrong merge and
> need to undo that", etc.

Understood, what does that have to do with anything?

> Liquid and dead are, in my opinion, completely orthogonal and solve two
> different problems: tracking what's safe to modify, and telling everyone
> else that something's gone amiss.

I'm afraid this can only mean you haven't fully understood what 'liquid'
is about. The primary distinction liquid makes is 'these are things that
will never disappear' and 'these are things that might disappear'.
Whereas dead heads is distinguishing between 'these are things we're
keeping' and 'these are things you should drop'. To say these are
unrelated is.. puzzling. My mental models of how to implement these two
concepts are nearly identical.

> (I told Martin to insist that pushkey wasn't the best choice at the
> sprint, but he must've forgotten). :o)

Nah, what he forgot was to tell you I thought you were crazy.

> > Also, I think there are some problems with a cset-base implementation
> > that are unaddressed here. Fundamentally, lines of development are not
> > the thing we actually care about, not heads. Consider:
> > 
> > 0-1-2-3-6
> >    \   /
> >     4-5
> > 
> > If I want to mark 1 and all descendants dead, it does not appear to be
> > enough to put a mark at 1:
> > 
> >     M
> >    /
> > 0-1-2-3-6
> >    \   /
> >     4-5
> > 
> > Looking at that last graph, it's not clear whether M was added before or
> > after 2. Thus it's not clear whether M kills 2 (case A) or 2 invalidates
> > M (case B).
> 
> The concept is invalidating ancestors, so you would commit a --kill
> changeset on top of 6 and a new child from 0 to make 0 alive. If you
> wanted M killed you would also have to commit a --kill on top of that,
> otherwise M keeps 1 alive.

And that, I think, is conceptually broken. I can know that I want "1 and
descendants" dead long before I know what I want to replace it with.
Having to commit an extra dummy cset (note that we actively reject empty
csets!) to have a living head at this point "sucks" from a user POV.

Again, dead "heads" are a boring special case of dead "anonymous
branches". If you're not talking about killing -whole lines of
development- after the fact, it's a non-starter. And killing branches is
logicially going to be about 'invalidating descendants' and not
'invalidating ancestors'.

> > In case A, it appears there's no way to undo M (short of destroying
> > history or marking M dead!). And in case B (what I gather you've
> > implemented), there's seems to be no way to mark "1 and all ancestors".
> > It's not even clear that adding 6(!) mark csets would do the trick,
> > without adding significant cleverness (and confusion) to the 'is this
> > dead?' logic.
> 
> A dead head can always be brought back to life by committing a live head
> on top of it.

Yes, and that (as I've already explained) is part of the problem. 

> > So the pushkey version is effectively an extension of history where each
> > cset has a deadness bit that's read/write.
> > 
> > [1] "Pushkey implementation" here means "something that's stored with a
> > mechanism outside of history and thus needs to be transmitted via
> > pushkey", eg like bookmarks. Pushkey itself doesn't implement any sort
> > of storage.
> 
> We'll then need to extend pushkey with enough knowledge about whether it
> kills heads here or there (push or pull) and compute much of what is
> already computed in discovery.

Extend pushkey? That's pretty much redundant. Pushkey is very abstract,
everything that uses pushkey defines its own add/remove and list
methods. I strongly suggest you actually look at how pushing bookmarks
work.

-- 
Mathematics is the supreme nostalgia of our time.




More information about the Mercurial-devel mailing list