[PATCH V2] rebase: move bookmark to destination for commits becoming empty (issue5627)

Jun Wu quark at fb.com
Sat Jul 22 01:18:39 UTC 2017


# HG changeset patch
# User Jun Wu <quark at fb.com>
# Date 1500686190 25200
#      Fri Jul 21 18:16:30 2017 -0700
# Branch stable
# Node ID 74b3107a9d9a22a38f09abaa0267d7ddb9165af9
# Parent  20436925e0803a98566c934aa3433fc75b6d2704
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 74b3107a9d9a
rebase: move bookmark to destination for commits becoming empty (issue5627)

When rebasing a changeset X and that changeset becomes empty, we should move
the bookmark on X to rebase destination.

This is a regression caused by scmutil.cleanupnodes refactoring.

Thanks Martin von Zweigbergk for providing improved path that works with
--keep!

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -513,5 +513,6 @@ class rebaseruntime(object):
             if self.collapsef:
                 collapsedas = newnode
-            clearrebased(ui, repo, self.state, self.skipped, collapsedas)
+            clearrebased(ui, repo, self.dest, self.state, self.skipped,
+                         collapsedas)
 
         clearstatus(repo)
@@ -1302,5 +1303,5 @@ def buildstate(repo, dest, rebaseset, co
     return originalwd, dest.rev(), state
 
-def clearrebased(ui, repo, state, skipped, collapsedas=None):
+def clearrebased(ui, repo, dest, state, skipped, collapsedas=None):
     """dispose of rebased revision at the end of the rebase
 
@@ -1308,4 +1309,13 @@ def clearrebased(ui, repo, state, skippe
     `collapsedas` node."""
     tonode = repo.changelog.node
+    # Move bookmark of skipped nodes to destination. This cannot be handled
+    # by scmutil.cleanupnodes since it will treat rev as removed (no successor)
+    # and move bookmark backwards.
+    bmchanges = [(name, tonode(dest))
+                 for rev in skipped
+                 for name in repo.nodebookmarks(tonode(rev))]
+    if bmchanges:
+        with repo.transaction('rebase') as tr:
+            repo._bookmarks.applychanges(repo, tr, bmchanges)
     mapping = {}
     for rev, newrev in sorted(state.items()):
diff --git a/tests/test-rebase-emptycommit.t b/tests/test-rebase-emptycommit.t
new file mode 100644
--- /dev/null
+++ b/tests/test-rebase-emptycommit.t
@@ -0,0 +1,52 @@
+  $ cat >> $HGRCPATH<<EOF
+  > [extensions]
+  > rebase=
+  > drawdag=$TESTDIR/drawdag.py
+  > EOF
+
+  $ hg init
+  $ hg debugdrawdag<<'EOS'
+  > B C
+  > |/
+  > A
+  > EOS
+
+  $ hg debugdrawdag<<'EOS'
+  > C
+  > |
+  > B
+  > EOS
+
+  $ hg bookmark -r 2 -i BOOK
+  $ hg log -G -T '{rev} {desc} {bookmarks}'
+  o  3 C
+  |
+  | o  2 C BOOK
+  | |
+  o |  1 B
+  |/
+  o  0 A
+  
+  $ hg rebase -r 2 -d 3 --keep
+  rebasing 2:dc0947a82db8 "C" (BOOK)
+  note: rebase of 2:dc0947a82db8 created no changes to commit
+  $ hg log -G -T '{rev} {desc} {bookmarks}'
+  o  3 C
+  |
+  | o  2 C BOOK
+  | |
+  o |  1 B
+  |/
+  o  0 A
+  
+  $ hg rebase -r 2 -d 3
+  rebasing 2:dc0947a82db8 "C" (BOOK)
+  note: rebase of 2:dc0947a82db8 created no changes to commit
+  saved backup bundle to $TESTTMP/.hg/strip-backup/dc0947a82db8-d21b92a4-rebase.hg (glob)
+  $ hg log -G -T '{rev} {desc} {bookmarks}'
+  o  2 C BOOK
+  |
+  o  1 B
+  |
+  o  0 A
+  


More information about the Mercurial-devel mailing list