diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -1316,9 +1316,9 @@ def pullrebase(orig, ui, repo, *args, ** 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 diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -355,15 +355,23 @@ def findrepo(p): 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 """ diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -464,12 +464,12 @@ class abstractsubrepo(object): 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 diff --git a/tests/test-rebase-pull.t b/tests/test-rebase-pull.t --- a/tests/test-rebase-pull.t +++ b/tests/test-rebase-pull.t @@ -78,6 +78,7 @@ Abort pull early if working dir is not c $ 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 @@ Abort pull early if another operation (h [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