[PATCH] bookmarks: allow moving a bookmark forward to a descendant

Kevin Bullock kbullock+mercurial at ringworld.org
Fri Mar 15 23:40:38 CDT 2013


# HG changeset patch
# User Kevin Bullock <kbullock at ringworld.org>
# Date 1363408747 18000
# Node ID 56dd55da2f7d3168d553fa01e38cb26244d2ee3f
# Parent  0bba1ff2ac7b26187a583ca53c08ec4baa372606
bookmarks: allow moving a bookmark forward to a descendant

Allow 'hg bookmark MARK', with an existing bookmark MARK, to move the
bookmark forward to the current or specified revision, if the target
revision is a descendant of the revision the bookmark currently points
to. Prints a status message including the revision the bookmark was
formerly at:

  $ hg bookmark Z
  moving bookmark 'Z' forward from 663762316562

Test coverage is added.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -808,8 +808,15 @@ def bookmark(ui, repo, mark=None, rev=No
         scmutil.checknewlabel(repo, mark, 'bookmark')
         return mark
 
-    def checkconflict(repo, mark, force=False):
+    def checkconflict(repo, mark, force=False, target=None):
         if mark in marks and not force:
+            if target:
+                anc = repo.changelog.ancestors([repo[target].rev()])
+                bmctx = repo[marks[mark]]
+                if bmctx.rev() in anc:
+                    ui.status(_("moving bookmark '%s' forward from %s\n") %
+                              (mark, short(bmctx.node())))
+                    return
             raise util.Abort(_("bookmark '%s' already exists "
                                "(use -f to force)") % mark)
         if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
@@ -852,11 +859,11 @@ def bookmark(ui, repo, mark=None, rev=No
         if inactive and mark == repo._bookmarkcurrent:
             bookmarks.setcurrent(repo, None)
             return
-        checkconflict(repo, mark, force)
+        tgt = cur
         if rev:
-            marks[mark] = scmutil.revsingle(repo, rev).node()
-        else:
-            marks[mark] = cur
+            tgt = scmutil.revsingle(repo, rev).node()
+        checkconflict(repo, mark, force, tgt)
+        marks[mark] = tgt
         if not inactive and cur == marks[mark]:
             bookmarks.setcurrent(repo, mark)
         marks.write()
diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t
--- a/tests/test-bookmarks.t
+++ b/tests/test-bookmarks.t
@@ -239,8 +239,8 @@ bookmark with reserved name
 
 bookmark with existing name
 
-  $ hg bookmark Z
-  abort: bookmark 'Z' already exists (use -f to force)
+  $ hg bookmark X2
+  abort: bookmark 'X2' already exists (use -f to force)
   [255]
 
   $ hg bookmark -m Y Z
@@ -279,7 +279,13 @@ incompatible options
 
 force bookmark with existing name
 
-  $ hg bookmark -f Z
+  $ hg bookmark -f X2
+  $ hg bookmark -fr1 X2
+
+forward bookmark to descendant without --force
+
+  $ hg bookmark Z
+  moving bookmark 'Z' forward from 663762316562
 
 list bookmarks
 


More information about the Mercurial-devel mailing list