# HG changeset patch # User Durham Goode # Date 2013-11-05 03:59:00 # Node ID 7d5e7799a29f97b261e08dcd585b83bdff127c6b # Parent 0151b61fed976372a4c26e6a3f09794ff87087b0 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 @@ -689,7 +689,7 @@ def inrebase(repo, originalwd, state): 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 @@ class phasecache(object): # 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 @@ Rebase and abort without generating new $ 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 ..