[PATCH STABLE V2] rebase: fix rebase aborts when 'tip-1' is public (issue4082)

Durham Goode durham at fb.com
Tue Nov 5 12:14:51 CST 2013


# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1383623940 28800
#      Mon Nov 04 19:59:00 2013 -0800
# Branch stable
# Node ID 4e5cb8149929ed1b2afa1fc44564429a31a9fc51
# Parent  7c4cf8367673e3100cda62927b096cdd9497a409
rebase: fix rebase aborts when 'tip-1' is public (issue4082)

When aborting a rebase where tip-1 is public, rebase would fail to undo the merge
state. This caused unexpected dirstate parents and also caused unshelve to
become unabortable (since it uses rebase under the hood).

The problem was that rebase uses -2 as a marker rev, and when it checked for
immutableness during the abort, -2 got resolved to the second to last entry in
the phase cache.

Adds a test for the fix. Add exception to phase code to prevent this in the
future.

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -692,7 +692,7 @@
 
 def abort(repo, originalwd, target, state):
     'Restore the repository to its original state'
-    dstates = [s for s in state.values() if s != nullrev]
+    dstates = [s for s in state.values() if s > nullrev]
     immutable = [d for d in dstates if not repo[d].mutable()]
     cleanup = True
     if immutable:
diff --git a/mercurial/phases.py b/mercurial/phases.py
--- a/mercurial/phases.py
+++ b/mercurial/phases.py
@@ -185,6 +185,8 @@
         # be replaced without us being notified.
         if rev == nullrev:
             return public
+        if rev < nullrev:
+            raise ValueError(_('cannot lookup negative revision'))
         if self._phaserevs is None or rev >= len(self._phaserevs):
             self._phaserevs = self.getphaserevs(repo, rebuild=True)
         return self._phaserevs[rev]
diff --git a/tests/test-rebase-abort.t b/tests/test-rebase-abort.t
--- a/tests/test-rebase-abort.t
+++ b/tests/test-rebase-abort.t
@@ -181,3 +181,46 @@
   
 
   $ cd ..
+
+rebase abort should not leave working copy in a merge state if tip-1 is public
+(issue4082)
+
+  $ hg init abortpublic
+  $ cd abortpublic
+  $ echo a > a && hg ci -Aqm a
+  $ hg book master
+  $ hg book foo
+  $ echo b > b && hg ci -Aqm b
+  $ hg up -q master
+  $ echo c > c && hg ci -Aqm c
+  $ hg phase -p -r .
+  $ hg up -q foo
+  $ echo C > c && hg ci -Aqm C
+  $ hg log -G --template "{rev} {desc} {bookmarks}"
+  @  3 C foo
+  |
+  | o  2 c master
+  | |
+  o |  1 b
+  |/
+  o  0 a
+  
+
+  $ hg rebase -d master -r foo
+  merging c
+  warning: conflicts during merge.
+  merging c incomplete! (edit conflicts, then use 'hg resolve --mark')
+  unresolved conflicts (see hg resolve, then hg rebase --continue)
+  [1]
+  $ hg rebase --abort
+  rebase aborted
+  $ hg log -G --template "{rev} {desc} {bookmarks}"
+  @  3 C foo
+  |
+  | o  2 c master
+  | |
+  o |  1 b
+  |/
+  o  0 a
+  
+  $ cd ..


More information about the Mercurial-devel mailing list