What should "hg update" do when there are bookmarks?

Angel Ezquerra angel.ezquerra at gmail.com
Fri Jun 8 04:46:50 CDT 2012


I've been thinking about the behavior of "hg update" when there are
bookmarks. I recently sent a patch that tried to implement what has
been discussed on this list. However, after thinking about it and
playing a bit with that patch I realized that I am not quite sure what
should be the behavior of mercurial in certain scenarios. In
particular using the patch that I sent I noticed that it is possible
to move "backwards", to an earlier revision (i.e. lower revision
number), when doing "hg update", which I think is weird.

So please let me specify several scenarios and what I think that
mercurial should or could do:

- [Scenario 1] 1 single head which is bookmarked:

    0--[1]--2--3--4--5--6 at bookmark1

There are two options:

A) give an error (no unbookmarked heads found above current revision)
B) assume we are on the "bookmark1" "branch", and thus update to 6
(i.e. at bookmark1)

A is safest, obviously, but I think that B is the most useful in the
context of using bookmarks as "branches".
In this context, a "bookmark branch" could be defined as the set of
revisions which are ancestors of a bookmark up to the first "branching
point". For example:

    0--1--2----4--5--6 at bookmark1
          |
          \--3

Here the "bookmark branch" bookmark1 would be:

               4--5--6 at bookmark1

In this context I think that B would make sense. I wonder if this is
what git does.


- [Scenario 2] 2 heads, 1 bookmarked, the current revision number is
lower than the unbookmarked head

    0--[1]--2----4--5--6 at bookmark1
            |
            \--3

If you are not using a fixed point font, in this (and all the
following) diagram(s) revisions 3 and 4 stem from 2, which is the only
revision that has more than 1 child.

I think in this scenario it is clear what must be done, which is to
update to the tipmost unbookmarked head. That is, after the update we
should see:

    0--1--2----4--5--6 at bookmark1
          |
          \--[3]


- [Scenario 3] 2 heads, one bookmarked, the current revision number is
higher than the unbookmarked head

    0--1--2----[4]--5--6 at bookmark1
          |
          \--3

Here it is not clear (to me) what should be done. I see 3 options:

A) give an error (no unbookmarked heads found above current revision)
B) assume we are on the "bookmark1" "branch", and thus update to 6
(i.e. to @bookmark1)

    0--1--2----4--5--[6 at bookmark1]
          |
          \--3

C) update to the unbookmarked head, 3, even though it is earlier than
the current revision

    0--1--2----4--5--6 at bookmark1
          |
          \--[3]

I'm not sure but I think that this could require using --force...

The safest is A, obviously.

C would be surprising IMHO (we'd be going back!) but perhaps
consistent (i.e. follow the simple rule: update to the tipmost
unbookmarked head). For this reason I think that we should follow the
rule that hg update" always goes forward (or stays at the current
revision), i.e. that it ignores all revision numbers which are lower
than the current revision.

B would probably be the most useful as discussed in Scenario 1.


- [Scenario 4] 2 heads, both bookmarked, the current revision number
is higher than the common ancestor of both heads:

    0--1--2----[4]--5--6 at bookmark1
          |
          \--3 at bookmark2

Note that this scenario could also happen if @bookmakr2 were later
than the current revision:

    0--1--2--[3]----5--6 at bookmark1
          |
          \-------4 at bookmark2

Here we could:

A) Give an error (no unbookmarked heads found above current revision)

B) Since the current revision would be on the "bookmark1 branch",
update to @bookmark1

    0--1--2----4--5--[6]@bookmark1
          |
          \--3 at bookmark2


- [Scenario 5] 2 heads, both bookmarked, the current revision number
is lower than the common ancestor of both :

    0--[1]--2----4--5--6 at bookmark1
            |
            \--3 at bookmark2


Again, I am not quite sure what should be the behavior:

A) Give an error (no unbookmarked heads found above current revision)

B) Update to the common ancestor of all heads

    0--1--[2]----4--5--6 at bookmark1
           |
           \--3 at bookmark2

B would mean that mercurial would update to the tipmost revision where
people have "branched out".
That is, it would consider all revisions beyond the common ancestor as
belonging to their respective "bookmark branches".
The main problem with B is that we would not be updating to a head,
although for me, conceptually, it would make sense according to the
definition of "bookmark branches". It would be updating to the tipmost
revision not belonging to any "bookmark branch".

I think that we should be consistent and either give an error in most
of these scenarios or follow the "bookmark branch" idea and update to
the current "bookmark branch" head.


What do you guys think?

Angel


More information about the Mercurial-devel mailing list