[PATCH] rebase: reset bookmarks (issue2265 and issue2873)
Stefano Tortarolo
stefano.tortarolo at gmail.com
Thu Jul 14 22:14:34 UTC 2011
# HG changeset patch
# User Stefano Tortarolo <stefano.tortarolo at gmail.com>
# Date 1310681425 -7200
# Node ID 23019dadbd1bdd89c99162db82f2943c16745543
# Parent 487818714d2f280ac575b353a7a21b5ca19a08a8
rebase: reset bookmarks (issue2265 and issue2873)
diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -14,7 +14,7 @@
http://mercurial.selenic.com/wiki/RebaseExtension
'''
-from mercurial import hg, util, repair, merge, cmdutil, commands
+from mercurial import hg, util, repair, merge, cmdutil, commands, bookmarks
from mercurial import extensions, ancestor, copies, patch
from mercurial.commands import templateopts
from mercurial.node import nullrev
@@ -154,6 +154,9 @@
targetancestors = set(repo.changelog.ancestors(target))
targetancestors.add(target)
+ # Keep track of the current bookmarks in order to reset them later
+ current_bookmarks = repo._bookmarks.copy()
+
sortedstate = sorted(state)
total = len(sortedstate)
pos = 0
@@ -214,6 +217,12 @@
if 'qtip' in repo.tags():
updatemq(repo, state, skipped, **opts)
+ # Nodeids are needed to reset bookmarks
+ nstate = dict([(repo[k].node(), repo[v].node()
+ if v != nullmerge else nullmerge
+ ) # This ugly trick is needed to avoid repo[nullmerge]
+ for k, v in state.iteritems()])
+
if not keepf:
# Remove no more useful revisions
rebased = [rev for rev in state if state[rev] != nullmerge]
@@ -225,6 +234,8 @@
# backup the old csets by default
repair.strip(ui, repo, repo[min(rebased)].node(), "all")
+ updatebookmarks(repo, nstate, current_bookmarks, **opts)
+
clearstatus(repo)
ui.note(_("rebase completed\n"))
if os.path.exists(repo.sjoin('undo')):
@@ -397,6 +408,19 @@
mq.series_dirty = True
mq.save_dirty()
+def updatebookmarks(repo, nstate, original_bookmarks, **opts):
+ 'Move bookmarks to their correct changesets'
+
+ current = repo._bookmarkcurrent
+ for k, v in original_bookmarks.iteritems():
+ if v in nstate:
+ if nstate[v] != nullmerge:
+ # reset the pointer if the bookmark was moved incorrectly
+ if k != current:
+ repo._bookmarks[k] = nstate[v]
+
+ bookmarks.write(repo)
+
def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
external):
'Store the current status to allow recovery'
diff --git a/tests/test-rebase-bookmarks.t b/tests/test-rebase-bookmarks.t
new file mode 100644
--- /dev/null
+++ b/tests/test-rebase-bookmarks.t
@@ -0,0 +1,85 @@
+ $ cat >> $HGRCPATH <<EOF
+ > [extensions]
+ > graphlog=
+ > rebase=
+ >
+ > [alias]
+ > tglog = log -G --template "{rev}: '{desc}' bookmarks: {bookmarks}\n"
+ > EOF
+
+Create a repo with several bookmarks
+ $ hg init a
+ $ cd a
+
+ $ echo a > a
+ $ hg ci -Am A
+ adding a
+
+ $ echo b > b
+ $ hg ci -Am B
+ adding b
+ $ hg book 'X'
+ $ hg book 'Y'
+
+ $ echo c > c
+ $ hg ci -Am C
+ adding c
+ $ hg book 'Z'
+
+ $ hg up -q 0
+
+ $ echo d > d
+ $ hg ci -Am D
+ adding d
+ created new head
+
+ $ hg tglog
+ @ 3: 'D' bookmarks:
+ |
+ | o 2: 'C' bookmarks: Y Z
+ | |
+ | o 1: 'B' bookmarks: X
+ |/
+ o 0: 'A' bookmarks:
+
+
+Move only rebased bookmarks
+
+ $ cd ..
+ $ hg clone -q a a1
+
+ $ cd a1
+ $ hg up -q Z
+
+ $ hg rebase --detach -s Y -d 3
+ saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
+
+ $ hg tglog
+ @ 3: 'C' bookmarks: Y Z
+ |
+ o 2: 'D' bookmarks:
+ |
+ | o 1: 'B' bookmarks: X
+ |/
+ o 0: 'A' bookmarks:
+
+Keep bookmarks to the correct rebased changeset
+
+ $ cd ..
+ $ hg clone -q a a2
+
+ $ cd a2
+ $ hg up -q Z
+
+ $ hg rebase -s 1 -d 3
+ saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
+
+ $ hg tglog
+ @ 3: 'C' bookmarks: Y Z
+ |
+ o 2: 'B' bookmarks: X
+ |
+ o 1: 'D' bookmarks:
+ |
+ o 0: 'A' bookmarks:
+
More information about the Mercurial-devel
mailing list