Patchwork bookmarks: allow moving a bookmark forward to a descendant

login
register
mail settings
Submitter Kevin Bullock
Date March 16, 2013, 4:40 a.m.
Message ID <56dd55da2f7d3168d553.1363408838@slower-than-infinity.lan>
Download mbox | patch
Permalink /patch/1132/
State Accepted
Commit 56dd55da2f7d3168d553fa01e38cb26244d2ee3f
Headers show

Comments

Kevin Bullock - March 16, 2013, 4:40 a.m.
# HG changeset patch
# User Kevin Bullock <kbullock@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.
Sean Farley - March 16, 2013, 5:23 a.m.
Kevin Bullock writes:

> # HG changeset patch
> # User Kevin Bullock <kbullock@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

Nice!
Augie Fackler - March 16, 2013, 7:45 a.m.
On Mar 15, 2013, at 9:40 PM, Kevin Bullock <kbullock+mercurial@ringworld.org> wrote:

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

LGTM

> 
> 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
> 
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

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