--- a/hgext/rebase.py Thu May 14 11:04:36 2015 +0200
+++ b/hgext/rebase.py Thu May 14 16:28:28 2015 -0500
@@ -839,16 +839,21 @@
raise
raise util.Abort(_('no rebase in progress'))
-def inrebase(repo, originalwd, state):
- '''check whether the working dir is in an interrupted rebase'''
+def needupdate(repo, state):
+ '''check whether we should `update --clean` away from a merge, or if
+ somehow the working dir got forcibly updated, e.g. by older hg'''
parents = [p.rev() for p in repo.parents()]
- if originalwd in parents:
+
+ # Are we in a merge state at all?
+ if len(parents) < 2:
+ return False
+
+ # We should be standing on the first as-of-yet unrebased commit.
+ firstunrebased = min([old for old, new in state.iteritems()
+ if new == nullrev])
+ if firstunrebased in parents:
return True
- for newrev in state.itervalues():
- if newrev in parents:
- return True
-
return False
def abort(repo, originalwd, target, state, activebookmark=None):
@@ -875,7 +880,7 @@
if cleanup:
# Update away from the rebase if necessary
- if inrebase(repo, originalwd, state):
+ if needupdate(repo, state):
merge.update(repo, originalwd, False, True, False)
# Strip from the first rebased revision
--- a/tests/test-rebase-abort.t Thu May 14 11:04:36 2015 +0200
+++ b/tests/test-rebase-abort.t Thu May 14 16:28:28 2015 -0500
@@ -241,3 +241,83 @@
o 0 a
$ cd ..
+
+Make sure we don't clobber changes in the working directory when the
+user has somehow managed to update to a different revision (issue4009)
+
+ $ hg init noupdate
+ $ cd noupdate
+ $ hg book @
+ $ echo original > a
+ $ hg add a
+ $ hg commit -m a
+ $ echo x > b
+ $ hg add b
+ $ hg commit -m b1
+ $ hg up 0
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ (leaving bookmark @)
+ $ hg book foo
+ $ echo y > b
+ $ hg add b
+ $ hg commit -m b2
+ created new head
+
+ $ hg rebase -d @ -b foo --tool=internal:fail
+ rebasing 2:070cf4580bb5 "b2" (tip foo)
+ unresolved conflicts (see hg resolve, then hg rebase --continue)
+ [1]
+
+ $ mv .hg/rebasestate ./ # so we're allowed to hg up like in mercurial <2.6.3
+ $ hg up -C 0 # user does other stuff in the repo
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+ $ mv rebasestate .hg/ # user upgrades to 2.7
+
+ $ echo new > a
+ $ hg up 1 # user gets an error saying to run hg rebase --abort
+ abort: rebase in progress
+ (use 'hg rebase --continue' or 'hg rebase --abort')
+ [255]
+
+ $ cat a
+ new
+ $ hg rebase --abort
+ rebase aborted
+ $ cat a
+ new
+
+ $ cd ..
+
+On the other hand, make sure we *do* clobber changes whenever we
+haven't somehow managed to update the repo to a different revision
+during a rebase (issue4661)
+
+ $ hg ini yesupdate
+ $ cd yesupdate
+ $ echo "initial data" > foo.txt
+ $ hg add
+ adding foo.txt
+ $ hg ci -m "initial checkin"
+ $ echo "change 1" > foo.txt
+ $ hg ci -m "change 1"
+ $ hg up 0
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ echo "conflicting change 1" > foo.txt
+ $ hg ci -m "conflicting 1"
+ created new head
+ $ echo "conflicting change 2" > foo.txt
+ $ hg ci -m "conflicting 2"
+
+ $ hg rebase -d 1 --tool 'internal:fail'
+ rebasing 2:e4ea5cdc9789 "conflicting 1"
+ unresolved conflicts (see hg resolve, then hg rebase --continue)
+ [1]
+ $ hg rebase --abort
+ rebase aborted
+ $ hg summary
+ parent: 3:b16646383533 tip
+ conflicting 2
+ branch: default
+ commit: (clean)
+ update: 1 new changesets, 2 branch heads (merge)