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 ..