rebase: provide detailed hint to abort message if working dir is not clean
Detailed hint message is now provided when 'pull --rebase' operation detects
unclean working dir, for example:
abort: uncommitted changes
(cannot pull with rebase: please commit or shelve your changes first)
Added tests for uncommitted merge, and for subrepo support verifying that same
hint is also passed to subrepo state check.
--- a/hgext/rebase.py Mon Jan 09 16:02:56 2017 +0900
+++ b/hgext/rebase.py Tue Jan 10 09:32:27 2017 +0100
@@ -1316,9 +1316,9 @@
ui.debug('--update and --rebase are not compatible, ignoring '
'the update flag\n')
- ui.debug('before rebase: ensure working dir is clean\n')
cmdutil.checkunfinished(repo)
- cmdutil.bailifchanged(repo)
+ cmdutil.bailifchanged(repo, hint=_('cannot pull with rebase: '
+ 'please commit or shelve your changes first'))
revsprepull = len(repo)
origpostincoming = commands.postincoming
--- a/mercurial/cmdutil.py Mon Jan 09 16:02:56 2017 +0900
+++ b/mercurial/cmdutil.py Tue Jan 10 09:32:27 2017 +0100
@@ -355,15 +355,23 @@
return p
-def bailifchanged(repo, merge=True):
+def bailifchanged(repo, merge=True, hint=None):
+ """ enforce the precondition that working directory must be clean.
+
+ 'merge' can be set to false if a pending uncommitted merge should be
+ ignored (such as when 'update --check' runs).
+
+ 'hint' is the usual hint given to Abort exception.
+ """
+
if merge and repo.dirstate.p2() != nullid:
- raise error.Abort(_('outstanding uncommitted merge'))
+ raise error.Abort(_('outstanding uncommitted merge'), hint=hint)
modified, added, removed, deleted = repo.status()[:4]
if modified or added or removed or deleted:
- raise error.Abort(_('uncommitted changes'))
+ raise error.Abort(_('uncommitted changes'), hint=hint)
ctx = repo[None]
for s in sorted(ctx.substate):
- ctx.sub(s).bailifchanged()
+ ctx.sub(s).bailifchanged(hint=hint)
def logmessage(ui, opts):
""" get the log message according to -m and -l option """
--- a/mercurial/subrepo.py Mon Jan 09 16:02:56 2017 +0900
+++ b/mercurial/subrepo.py Tue Jan 10 09:32:27 2017 +0100
@@ -464,12 +464,12 @@
return _("uncommitted changes in subrepository '%s'"
) % subrelpath(self)
- def bailifchanged(self, ignoreupdate=False):
+ def bailifchanged(self, ignoreupdate=False, hint=None):
"""raise Abort if subrepository is ``dirty()``
"""
dirtyreason = self.dirtyreason(ignoreupdate=ignoreupdate)
if dirtyreason:
- raise error.Abort(dirtyreason)
+ raise error.Abort(dirtyreason, hint=hint)
def basestate(self):
"""current working directory base state, disregarding .hgsubstate
--- a/tests/test-rebase-pull.t Mon Jan 09 16:02:56 2017 +0900
+++ b/tests/test-rebase-pull.t Tue Jan 10 09:32:27 2017 +0100
@@ -78,6 +78,7 @@
$ echo L1-mod > L1
$ hg pull --rebase
abort: uncommitted changes
+ (cannot pull with rebase: please commit or shelve your changes first)
[255]
$ hg update --clean --quiet
@@ -95,6 +96,41 @@
[255]
$ hg histedit --abort --quiet
+Abort pull early with pending uncommitted merge:
+
+ $ cd ..
+ $ hg clone --noupdate c d
+ $ cd d
+ $ hg tglog
+ o 1: 'C2'
+ |
+ o 0: 'C1'
+
+ $ hg update --quiet 0
+ $ echo M1 > M1
+ $ hg commit --quiet -Am M1
+ $ hg update --quiet 1
+ $ hg merge 2
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ hg pull --rebase
+ abort: outstanding uncommitted merge
+ (cannot pull with rebase: please commit or shelve your changes first)
+ [255]
+ $ hg update --clean --quiet
+
+Abort pull early with unclean subrepo:
+ $ echo s = s > .hgsub
+ $ hg add .hgsub
+ $ hg init s
+ $ hg commit -m "generated a subrepo"
+ $ echo a > s/a
+ $ hg -R s add s/a
+ $ hg pull --rebase
+ abort: uncommitted changes in subrepository 's'
+ (cannot pull with rebase: please commit or shelve your changes first)
+ [255]
+
Invoke pull --rebase and nothing to rebase:
$ cd ../c