[PATCH STABLE HACK] rebase: crude hack to fix crash when run with --collapse and --keepbranch

Greg Ward greg-hg at gerg.ca
Mon Mar 22 17:23:50 CDT 2010


# HG changeset patch
# User Greg Ward <greg-hg at gerg.ca>
# Date 1269296488 14400
# Branch stable
# Node ID 997be3f2026748d68325eae05c99abfda9467c42
# Parent  a1cb8ca051c01612ea0e6161b4d4419f6954e251
rebase: crude hack to fix crash when run with --collapse and --keepbranch.
(issue2100)

This is almost certainly NOT the right fix.  The change to the test is
good because it demonstrates the bug.  But the fix itself is rather
nasty; I couldn't think of a nice clean way to do it, so I hacked this
mess together in hopes of prompting someone to suggest a better way.

Suggestions?

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -137,6 +137,7 @@
             if extrafn:
                 raise error.ParseError(
                     'rebase', _('cannot use both keepbranches and extrafn'))
+            # XXX not enough: what if we are collapsing multiple changesets?
             def extrafn(ctx, extra):
                 extra['branch'] = ctx.branch()
 
@@ -145,6 +146,8 @@
             targetancestors = set(repo.changelog.ancestors(target))
             targetancestors.add(target)
 
+        if collapsef and keepbranchesf:
+            branches = set()
         for rev in sorted(state):
             if state[rev] == -1:
                 ui.debug("rebasing %d:%s\n" % (rev, repo[rev]))
@@ -169,6 +172,8 @@
                     # Skip commit if we are collapsing
                     repo.dirstate.setparents(repo[p1].node())
                     newrev = None
+                    if keepbranchesf:
+                        branches.add(repo[rev].branch())
                 # Update the state
                 if newrev is not None:
                     state[rev] = repo[newrev].rev()
@@ -182,6 +187,17 @@
         ui.note(_('rebase merging completed\n'))
 
         if collapsef:
+            if keepbranchesf:
+                if len(branches) > 1:
+                    raise util.Abort(_(
+                        'cannot collapse and keep branches: '
+                        'found multiple named branches'))
+                # HAAAACCK!!  only the code that handles keepbranchesf
+                # should have to know how to record the branch
+                extra = {'branch': branches.pop()}
+            else:
+                extra = {}
+
             p1, p2 = defineparents(repo, min(state), target,
                                                         state, targetancestors)
             commitmsg = 'Collapsed revision'
@@ -190,7 +206,7 @@
                     commitmsg += '\n* %s' % repo[rebased].description()
             commitmsg = ui.edit(commitmsg, repo.ui.username())
             newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
-                                                    extra=extrafn)
+                                                    extra=extra)
 
         if 'qtip' in repo.tags():
             updatemq(repo, state, skipped, **opts)
diff --git a/tests/test-rebase-collapse b/tests/test-rebase-collapse
--- a/tests/test-rebase-collapse
+++ b/tests/test-rebase-collapse
@@ -172,4 +172,26 @@
 
 echo "Expected A, B, C, D, F"
 hg manifest
-exit 0
+
+createrepocomplex() {
+    cd $BASE
+    rm -rf a
+    hg init a
+    cd a
+    addcommit "A" 0
+    hg branch b
+    addcommit "B" 1
+    addcommit "C" 2
+    hg update default
+    addcommit "D" 3
+}
+
+echo
+echo '% Rebase with --collapse and --keepbranch'
+createrepocomplex > /dev/null 2>&1
+hg update b
+hg glog  --template '{rev}: {desc}\n'
+hg rebase --collapse --keepbranch -d 3 2>&1 | sed 's/\(saving bundle to \).*/\1/'
+hg glog  --template '{rev}: {desc}\n'
+echo "Expected A, B, C, D"
+hg manifest
diff --git a/tests/test-rebase-collapse.out b/tests/test-rebase-collapse.out
--- a/tests/test-rebase-collapse.out
+++ b/tests/test-rebase-collapse.out
@@ -213,3 +213,33 @@
 C
 D
 F
+
+% Rebase with --collapse and --keepbranch
+2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+o  3: D
+|
+| @  2: C
+| |
+| o  1: B
+|/
+o  0: A
+
+saving bundle to 
+adding branch
+adding changesets
+adding manifests
+adding file changes
+added 2 changesets with 3 changes to 3 files
+rebase completed
+@  2: Collapsed revision
+|  * B
+|  * C
+o  1: D
+|
+o  0: A
+
+Expected A, B, C, D
+A
+B
+C
+D


More information about the Mercurial-devel mailing list