[PATCH 0 of 6] improve help and hints, then add 'update --bookmark'

Matt Mackall mpm at selenic.com
Wed Dec 7 19:14:13 CST 2011


On Wed, 2011-12-07 at 17:01 -0600, Kevin Bullock wrote:
> On Dec 7, 2011, at 4:18 PM, Matt Mackall wrote:
> 
> > On Wed, 2011-12-07 at 14:01 -0600, Kevin Bullock wrote:
> >> On Dec 7, 2011, at 12:32 PM, Idan Kamara wrote:
> >> 
> >>> Why would you not want to move the *active* bookmark when updating to a
> >>> descendant? When opening issue2894 this is the behavior I expected, others
> >>> disagreed but I didn't understand the use cases in which this is undesired.
> >> 
> >> 
> >> The use case is using bookmarks as a replacement for localtags (and Matt has explicitly stated he considers localtags deprecated in favor of bookmarks). Example:
> >> 
> >> Alice has done a major experimental refactoring and wants Bob to review it. She bookmarks the last non-experimental revision as 'last-stable', and the head as 'experimental'. Bob clones (with bookmarks) and updates to 'last-stable' to inspect it. He then runs `hg update` to inspect the head of Alice's work.
> >> 
> >> On no account should the 'last-stable' bookmark move in this case.
> > 
> > Ok, let's compare some use cases:
> > 
> > Case 1:
> > 
> > Alice sets a bookmark "whataliceisworkingon". Alice does some work.
> > Alice commits, pulls, merges, now "whataliceisworkingon" points at her
> > merge. Alice then pushes, does some more work, pulls, then does an "hg
> > update" to merge her pull into her working directory, then commits. Now
> > "whataliceisworkingon" should point to her latest commit (but the update
> > currently loses it as of 2.0).
> > 
> > Question 1a: is there something "un-Mercurial" about Alice's use of
> > update here? 
> 
> No, I don't think so.
> 
> > Question 1b: why should the workflow of merging-by-update require
> > special attention to bookmarks, while merge does not?
> 
> Because (I'm arguing) it's not the only workflow that meaningfully
> involves bookmarks. But it's a tricky thing, and I think this is what
> led Git to make their `merge` command move refs instead of making
> `checkout` do it.

Well, the thing is 'git pull' is the same as 'hg pull && hg merge' OR
'hg pull && hg update' (the latter being about the closest thing we have
to git's "fast-forward merge"). And 'git pull' is the pattern that we're
failing to emulate. Because 'git pull' is the normal way git users 'move
forward' and 'hg pull && hg merge|update' is the normal way for hg
users, 'git checkout' simply isn't terribly relevant for comparison
here.

> > Question 1c: will users forget to use -B or whatever basically every
> > time it's relevant?
> 
> Hopefully not, if we give them enough hints in the appropriate places.

And I strongly disagree here. Real users are lazy, habitual, etc. If you
give them an obstacle 5% of the time, they will trip over that obstacle
99% of the time it's present.

> > Question 1d: how can we warn people (who are mostly error-blind already
> > or possibly using a tool that hides the note) that they've left their
> > active bookmark behind on "hg update" if we decide to do that?
> 
> Hint on pull, as Idan suggested; if tools are hiding it, that's beyond what I care about. I only use the CLI :)

Unfortunately, the percentage of Mercurial users who never touch a
command line is quite significant.

> > Question 1e: will users need to do "hg book -f whataliceisworkingon" to
> > manually fix things every time they forget?
> 
> That'd be one fix, but the other would be: `hg up OLD; hg up -B`.

...and now we've lost our merge work.

> > Question 1f: what could possibly go wrong with a workflow that basically
> > implies a --force because users can never remember to do it 'right' the
> > first time?
> 
> The idea of this patch is to avoid necessitating a --force to begin with, which is currently required.

You lost me. Where is a force required in my proposal?

> Alternative idea: what about making `hg bookmark MARK` willing to update a bookmark to a descendant without requiring --force (or any other switch)? AFAICT, the implementation of this would be trivial (simpler than my patch).
> 
> > Case 2:
> > 
> > Alice has done a major experimental refactoring and wants Bob to review
> > it. She bookmarks the last non-experimental revision as 'last-stable',
> > and the head as 'experimental'. Bob clones (with bookmarks) and updates
> > to 'last-stable' to inspect it. He then runs `hg update` to inspect the
> > head of Alice's work. This does or does not move the last-stable
> > bookmark depending on how case 1 is resolved.
> > 
> > Question 2a: why is Bob using "hg update" (find the latest) here rather
> > than "hg update experimental" (jump to a specific revision). Does he
> > have some good reason for thinking experimental is a descendant?
> 
> I think it's perfectly rational to assume that experimental is a
> descendent of last-stable, yes. I know that if I were in Bob's shoes,
> I would absolutely omit the 'experimental' from the command line.
> 
> > Question 2b: is a label that shouldn't be moved automatically really a
> > good use case for bookmarks?
> 
> Maybe. I'm trying to preserve a use case you yourself have endorsed (that of using bookmarks as a localtags replacement). :)

Localtags aren't shared, so there's no such use case with localtags.

> As it stands today, bookmarks are better suited to this use case
> (meaning users that are using bookmarks _now_ may well be doing things
> like this) than they are to feature-branching. And ultimately I _do_
> want bookmarks to work well for feature-branching.

And as far as I can tell, if we support case 2 over case 1, then we have
completely failed to "work well" because existing Mercurial users have
to retrain themselves.

> > Question 2c: is this use case important/sensible/frequent enough to
> > justify the regular annoyance implied by 1c through 1f?
> 
> In the absence of localtags, and assuming bookmarks move surprisingly at times, how do you propose this use case be solved? 

We ignore it. I think case 1 is overwhelming more common and important.
If we can't do both 'right', then we favor the important one.

I frankly don't care much about this case: the whole point of bookmarks
vs plain old tags is that they automatically move.

Bear in mind that the space of possible label types is large: we could
have at least the Cartesian product of shared|local x historic|ephemeral
x mutable|immutable x moving|stationary x concurrent|retrospective and
we're already up to 32 distinct types. Instead, we try to cover the
useful space with as few types as possible:

tags: shared, historic, mutable, stationary, retrospective
branches: shared, historic, immutable, stationary, concurrent
bookmarks: shared(*), ephemeral, mutable, moving(*), retrospective
localtags: local, ephemeral, mutable, stationary, retrospective

(bookmarks are shared only on clone and moved only when active)

Also note that branch marks effectively create a virtual label class:

branch tips: shared, ephemeral, immutable, moving, concurrent

Now if you want something that's simultaneously sharable, ephemeral, and
stationary, you'll have to settle for 2 out of 3: either tags or
bookmarks. But I think we cover plenty of this space, and there's very
little you can usefully do with a localtag that can't be done with a
bookmark, so we can deprecate them (and around here, that means "hide",
not "remove").

-- 
Mathematics is the supreme nostalgia of our time.




More information about the Mercurial-devel mailing list