strip: move bookmarks to nearest ancestor rather than '.' stable
authorAugie Fackler <raf@durin42.com>
Thu, 26 Jul 2012 16:57:50 -0500
branchstable
changeset 17264 ec7b9bec19c9
parent 17263 c4ebdc36c17e
child 17265 c30307eeec4b
strip: move bookmarks to nearest ancestor rather than '.' If you've got this graph: 0-1-2 \ 3 and 3 is checked out, 2 is bookmarked with "broken", and you do "hg strip 2", the bookmark will move to 3, not 1. That's always struck me as a bug. This change makes bookmarks move to the tipmost ancestor of the stripped set rather than the currently-checked-out revision, which is what I always expected should happen.
mercurial/commands.py
mercurial/repair.py
tests/test-bookmarks-strip.t
tests/test-bookmarks.t
--- a/mercurial/commands.py	Fri Jul 27 12:33:48 2012 -0500
+++ b/mercurial/commands.py	Thu Jul 26 16:57:50 2012 -0500
@@ -1298,10 +1298,20 @@
                                editor=editor,
                                extra=extra)
 
+        current = repo._bookmarkcurrent
+        marks = old.bookmarks()
         node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
         if node == old.node():
             ui.status(_("nothing changed\n"))
             return 1
+        elif marks:
+            ui.debug('moving bookmarks %r from %s to %s\n' %
+                     (marks, old.hex(), hex(node)))
+            for bm in marks:
+                repo._bookmarks[bm] = node
+                if bm == current:
+                    bookmarks.setcurrent(repo, bm)
+            bookmarks.write(repo)
     else:
         e = cmdutil.commiteditor
         if opts.get('force_editor'):
--- a/mercurial/repair.py	Fri Jul 27 12:33:48 2012 -0500
+++ b/mercurial/repair.py	Thu Jul 26 16:57:50 2012 -0500
@@ -111,6 +111,13 @@
         saverevs.difference_update(descendants)
     savebases = [cl.node(r) for r in saverevs]
     stripbases = [cl.node(r) for r in tostrip]
+    rset = ' or '.join([str(r) for r in tostrip])
+    newbmtarget = repo.revs('sort(heads(ancestors(%r) - (%r)), -rev)',
+                            rset, rset)
+    if newbmtarget:
+        newbmtarget = newbmtarget[0]
+    else:
+        newbmtarget = '.'
 
     bm = repo._bookmarks
     updatebm = []
@@ -174,7 +181,7 @@
                     ui.warn(_('error removing %s: %s\n') % (undofile, str(e)))
 
         for m in updatebm:
-            bm[m] = repo['.'].node()
+            bm[m] = repo[newbmtarget].node()
         bookmarks.write(repo)
     except: # re-raises
         if backupfile:
@@ -192,4 +199,3 @@
         # Multiple branches involved in strip. Will allow branchcache to become
         # invalid and later on rebuilt from scratch
         repo.destroyed()
-
--- a/tests/test-bookmarks-strip.t	Fri Jul 27 12:33:48 2012 -0500
+++ b/tests/test-bookmarks-strip.t	Thu Jul 26 16:57:50 2012 -0500
@@ -60,8 +60,8 @@
 list bookmarks
 
   $ hg book
-     test                      1:8cf31af87a2b
-     test2                     1:8cf31af87a2b
+     test                      0:5c9ad3787638
+     test2                     0:5c9ad3787638
 
 immediate rollback and reentrancy issue
 
--- a/tests/test-bookmarks.t	Fri Jul 27 12:33:48 2012 -0500
+++ b/tests/test-bookmarks.t	Thu Jul 26 16:57:50 2012 -0500
@@ -390,3 +390,70 @@
   $ echo "925d80f479bc z" > .hg/bookmarks
   $ hg book
   no bookmarks set
+
+test stripping a non-checked-out but bookmarked revision
+
+  $ hg --config extensions.graphlog= log --graph
+  o  changeset:   4:9ba5f110a0b3
+  |  branch:      test
+  |  tag:         tip
+  |  parent:      2:db815d6d32e6
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     y
+  |
+  | @  changeset:   3:125c9a1d6df6
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     x
+  |
+  o  changeset:   2:db815d6d32e6
+  |  parent:      0:f7b1eb17ad24
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     2
+  |
+  | o  changeset:   1:925d80f479bb
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     1
+  |
+  o  changeset:   0:f7b1eb17ad24
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     0
+  
+  $ hg book should-end-on-two
+  $ hg co --clean 4
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg book four
+  $ hg --config extensions.mq= strip 3
+  saved backup bundle to * (glob)
+should-end-on-two should end up pointing to revision 2, as that's the
+tipmost surviving ancestor of the stripped revision.
+  $ hg --config extensions.graphlog= log --graph
+  @  changeset:   3:9ba5f110a0b3
+  |  branch:      test
+  |  bookmark:    four
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     y
+  |
+  o  changeset:   2:db815d6d32e6
+  |  bookmark:    should-end-on-two
+  |  parent:      0:f7b1eb17ad24
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     2
+  |
+  | o  changeset:   1:925d80f479bb
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     1
+  |
+  o  changeset:   0:f7b1eb17ad24
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     0
+