|| ||Greg Ward <greg-hg-AT-gerg.ca> |
|| ||Matt Mackall <mpm-AT-selenic.com> |
|| ||Re: [PATCH] rollback: try to prevent nasty messes with shared clones |
|| ||Wed, 14 Sep 2011 21:45:16 -0400|
|| ||Article, Thread
On Wed, Sep 14, 2011 at 2:52 PM, Matt Mackall <firstname.lastname@example.org> wrote:
> On Tue, 2011-09-13 at 21:26 -0400, Greg Ward wrote:
>> # HG changeset patch
>> # User Greg Ward <email@example.com>
>> # Date 1315963560 14400
>> # Node ID 20561153542c382a2ef33ba9e296c2f73d3606c3
>> # Parent 06c791dab7707265e830f0e4ba343aad0a4c8df5
>> rollback: try to prevent nasty messes with shared clones.
> I think this patch is fine on its own, modulo error message bike
Always my favourite part of any Mercurial contribution. ;-) I'm
pleasantly surprised that people are apparently holding back and
waiting for the technical stuff to be properly vetted before
starting the bikeshedding.
> But I'm a little worried that we're going to slowly collect a
> bunch of similar hacks for different tools that do non-append history
> changes (mq, strip, etc.). Worse, we might build expectations of safety
> where we can't provide it.
> So let's step back and look at the big picture:
> - multiple working directories can share the same store
> - there is no record in the store of the number or location of sharers
> - there's no good way to add that information:
> - sharers may be across a network
> - sharers may be moved, copied, or deleted WITHOUT using hg
> - any sort of locking/reference counting scheme is inherently broken
> - one sharer may remove a changeset that's "in use" by another
> - the primary user may be completely unaware that a repo is shared
> - core commands that modify history: rollback, recover
> - extensions that modify history: mq, rebase, etc.
> So annoying!
No kidding. Making software flexible, safe, and correct is hard work.
Wish I still had my magic wand from kindergarten.
> In terms of rollback, the "most recent transaction" is a global state
> that individual sharers don't have great visibility into and may race
> against. So your wdir fix can basically be thought of as "sharer A
> shouldn't accidentally nuke sharer B's work". Is there a way we can
> generalize this notion? Or is rollback a special case in that it
> operates on the singleton journal?
strip is awfully similar in that it affects both the store and the
working dir. And, AFAICT all history modification is based on either
strip or rollback, so if we can improve both operations, we're better
But strip is harder in a way because it's a one-off, unlike the
two-step dance of writing a transaction and then later rolling it
back. So there's no obvious way to write something analogous to
"transaction written from working dir X". And strip is just as capable
of leaving orphaned working dirs.
The big difference, of course, is that you have to know about and
understand .hg/hgrc to use strip. Right away that cuts the potential
audience by probably 2/3.
My take on strip is that the only way to prevent orphaned working dirs
is with a registry of shared clones in the real .hg/store. (strip
could visit each extant sharer and check if it's using any of the
changesets due to be stripped.) That's impossible to do 100%
correctly, but maybe an 80%-good-enough registry would help. But that
has very little to do with my proposed improvement to rollback, so I'm
going to set it aside for the time being.
> Also, we have another issue here. Imagine a team where everyone shares a
> repo on z:\project\foo to c:\build\foo because of some legacy/habit. Now
> everyone's wdir token is the same! This issue is analogous to storing
> PIDs in a lockfile on a shared filesystem - we need a hostname or IP
> address in there too.
Oops! Good point. Should be easy to fix.
> Finally, I think we should try to sort out the issues here first:
> That may bring a bit more clarity to the semantics of rollback on the
> working directory.
To keep the conversation clearer, I'll excerpt that message here:
> Second, rolling back the dirstate should be seen as a side-effect of truncating
> history: we don't want the dirstate to keep pointing at truncated history. So if
> dirstate points at a revision that's not being truncated, no action should be taken.
> hg co stable
> echo foo > bar
> hg ci -Am "add new file bar"
> hg co default
> hg rollback -> should remove tip commit without jumping to stable
Ahh, that explains some of the strange side effects I have seen of
rollback. Current behaviour is indeed surprising.
Hey waitasec: that might fix issue2998 for free. Hmmm.
> Similarly, we shouldn't mess with rolling back the dirstate (or even storing it!)
> if the last transaction had nothing to do with the dirstate. Example:
> hg pull
> hg add foo
> hg rollback -> shouldn't unadd foo
> Neither of these cases should require --force.
Seems like a sensible change.
I'll see if I can figure out one or both of these and then get back to
the safety issue.
Mercurial-devel mailing list
to post comments)