diff --git a/hgext/absorb.py b/hgext/absorb.py --- a/hgext/absorb.py +++ b/hgext/absorb.py @@ -51,6 +51,7 @@ pycompat, registrar, scmutil, + state as statemod, util, ) from mercurial.utils import ( @@ -1011,7 +1012,7 @@ with repo.wlock(), repo.lock(): if not opts['dry_run']: - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) state = absorb(ui, repo, pats=pats, opts=opts) if sum(s[0] for s in state.chunkstats.values()) == 0: diff --git a/hgext/fix.py b/hgext/fix.py --- a/hgext/fix.py +++ b/hgext/fix.py @@ -132,6 +132,7 @@ pycompat, registrar, scmutil, + state as statemod, util, worker, ) @@ -349,7 +350,7 @@ for rev in revs: checkfixablectx(ui, repo, repo[rev]) if revs: - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) checknodescendants(repo, revs) if opts.get('working_dir'): revs.add(wdirrev) diff --git a/hgext/histedit.py b/hgext/histedit.py --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -1508,7 +1508,7 @@ try: keep = opts.get('keep') revs = opts.get('rev', [])[:] - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) cmdutil.bailifchanged(repo) if os.path.exists(os.path.join(repo.path, 'histedit-state')): @@ -1940,7 +1940,7 @@ rules = opts.get('commands', '') force = opts.get('force') - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) cmdutil.bailifchanged(repo) topmost = repo.dirstate.p1() @@ -2313,7 +2313,7 @@ def extsetup(ui): cmdutil.summaryhooks.add('histedit', summaryhook) - cmdutil.unfinishedstates.append( + statemod.unfinishedstates.append( ['histedit-state', False, True, _('histedit in progress'), _("use 'hg histedit --continue' or 'hg histedit --abort'")]) cmdutil.afterresolvedstates.append( diff --git a/hgext/phabricator.py b/hgext/phabricator.py --- a/hgext/phabricator.py +++ b/hgext/phabricator.py @@ -50,7 +50,6 @@ from mercurial.node import bin, nullid from mercurial.i18n import _ from mercurial import ( - cmdutil, context, encoding, error, @@ -64,6 +63,7 @@ registrar, scmutil, smartset, + state as statemod, tags, templatefilters, templateutil, @@ -552,7 +552,7 @@ if not revs: raise error.Abort(_(b'phabsend requires at least one changeset')) if opts.get(b'amend'): - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) # {newnode: (oldnode, olddiff, olddrev} oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs]) diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -1067,7 +1067,7 @@ raise error.Abort(_('cannot specify both a revision and a source')) if not inmemory: - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) cmdutil.bailifchanged(repo) if ui.configbool('commands', 'rebase.requiredest') and not destf: @@ -1147,7 +1147,7 @@ rebase_rebasing_wcp=rebasingwcp) if inmemory and rebasingwcp: # Check these since we did not before. - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) cmdutil.bailifchanged(repo) if not destf: @@ -1822,7 +1822,7 @@ ui.debug('--update and --rebase are not compatible, ignoring ' 'the update flag\n') - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) cmdutil.bailifchanged(repo, hint=_('cannot pull with rebase: ' 'please commit or shelve your changes first')) @@ -1950,7 +1950,7 @@ entry[1].append(('t', 'tool', '', _("specify merge tool for rebase"))) cmdutil.summaryhooks.add('rebase', summaryhook) - cmdutil.unfinishedstates.append( + statemod.unfinishedstates.append( ['rebasestate', False, False, _('rebase in progress'), _("use 'hg rebase --continue' or 'hg rebase --abort'")]) cmdutil.afterresolvedstates.append( diff --git a/hgext/record.py b/hgext/record.py --- a/hgext/record.py +++ b/hgext/record.py @@ -19,6 +19,7 @@ error, extensions, registrar, + state as statemod, ) cmdtable = {} @@ -119,7 +120,7 @@ overrides = {('experimental', 'crecord'): False} with ui.configoverride(overrides, 'record'): - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) cmdutil.dorecord(ui, repo, committomq, cmdsuggest, False, cmdutil.recordfilter, *pats, **opts) diff --git a/hgext/shelve.py b/hgext/shelve.py --- a/hgext/shelve.py +++ b/hgext/shelve.py @@ -48,6 +48,7 @@ registrar, repair, scmutil, + state as statemod, templatefilters, util, vfs as vfsmod, @@ -445,7 +446,7 @@ def createcmd(ui, repo, pats, opts): """subcommand that creates a new shelve""" with repo.wlock(): - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) return _docreatecmd(ui, repo, pats, opts) def _docreatecmd(ui, repo, pats, opts): @@ -935,7 +936,7 @@ abortf = opts.get('abort') continuef = opts.get('continue') if not abortf and not continuef: - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) shelved = list(shelved) if opts.get("name"): shelved.append(opts["name"]) @@ -1139,9 +1140,10 @@ return createcmd(ui, repo, pats, opts) def extsetup(ui): - cmdutil.unfinishedstates.append( + statemod.unfinishedstates.append( [shelvedstate._filename, False, False, _('unshelve already in progress'), _("use 'hg unshelve --continue' or 'hg unshelve --abort'")]) cmdutil.afterresolvedstates.append( [shelvedstate._filename, _('hg unshelve --continue')]) + diff --git a/hgext/strip.py b/hgext/strip.py --- a/hgext/strip.py +++ b/hgext/strip.py @@ -8,7 +8,6 @@ from mercurial.i18n import _ from mercurial import ( bookmarks as bookmarksmod, - cmdutil, error, hg, lock as lockmod, @@ -18,6 +17,7 @@ registrar, repair, scmutil, + state as statemod, util, ) nullid = nodemod.nullid @@ -31,8 +31,23 @@ # leave the attribute unspecified. testedwith = 'ships-with-hg-core' -def checklocalchanges(repo, force=False): - cmdutil.checkunfinished(repo) +def checksubstate(repo, baserev=None): + '''return list of subrepos at a different revision than substate. + Abort if any subrepos have uncommitted changes.''' + inclsubs = [] + wctx = repo[None] + if baserev: + bctx = repo[baserev] + else: + bctx = wctx.p1() + for s in sorted(wctx.substate): + wctx.sub(s).bailifchanged(True) + if s not in bctx.substate or bctx.sub(s).dirty(): + inclsubs.append(s) + return inclsubs + +def checklocalchanges(repo, force=False, excsuffix=''): + statemod.checkunfinished(repo) s = repo.status() if not force: cmdutil.bailifchanged(repo) diff --git a/hgext/transplant.py b/hgext/transplant.py --- a/hgext/transplant.py +++ b/hgext/transplant.py @@ -35,6 +35,7 @@ revset, scmutil, smartset, + state as statemod, util, vfs as vfsmod, ) @@ -675,7 +676,7 @@ if not tp.canresume(): raise error.Abort(_('no transplant to continue')) else: - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) cmdutil.bailifchanged(repo) sourcerepo = opts.get('source') @@ -757,7 +758,7 @@ return n and nodemod.hex(n) or '' def extsetup(ui): - cmdutil.unfinishedstates.append( + statemod.unfinishedstates.append( ['transplant/journal', True, False, _('transplant in progress'), _("use 'hg transplant --continue' or 'hg update' to abort")]) diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -42,6 +42,7 @@ rewriteutil, scmutil, smartset, + state as statemod, subrepoutil, templatekw, templater, @@ -265,7 +266,7 @@ will be left in place, so the user can continue working. """ - checkunfinished(repo, commit=True) + statemod.checkunfinished(repo, commit=True) wctx = repo[None] merge = len(wctx.parents()) > 1 if merge: @@ -3313,47 +3314,6 @@ # - (desturl, destbranch, destpeer, outgoing) summaryremotehooks = util.hooks() -# A list of state files kept by multistep operations like graft. -# Since graft cannot be aborted, it is considered 'clearable' by update. -# note: bisect is intentionally excluded -# (state file, clearable, allowcommit, error, hint) -unfinishedstates = [ - ('graftstate', True, False, _('graft in progress'), - _("use 'hg graft --continue' or 'hg graft --stop' to stop")), - ('updatestate', True, False, _('last update was interrupted'), - _("use 'hg update' to get a consistent checkout")) - ] - -def checkunfinished(repo, commit=False): - '''Look for an unfinished multistep operation, like graft, and abort - if found. It's probably good to check this right before - bailifchanged(). - ''' - # Check for non-clearable states first, so things like rebase will take - # precedence over update. - for f, clearable, allowcommit, msg, hint in unfinishedstates: - if clearable or (commit and allowcommit): - continue - if repo.vfs.exists(f): - raise error.Abort(msg, hint=hint) - - for f, clearable, allowcommit, msg, hint in unfinishedstates: - if not clearable or (commit and allowcommit): - continue - if repo.vfs.exists(f): - raise error.Abort(msg, hint=hint) - -def clearunfinished(repo): - '''Check for unfinished operations (as above), and clear the ones - that are clearable. - ''' - for f, clearable, allowcommit, msg, hint in unfinishedstates: - if not clearable and repo.vfs.exists(f): - raise error.Abort(msg, hint=hint) - for f, clearable, allowcommit, msg, hint in unfinishedstates: - if clearable and repo.vfs.exists(f): - util.unlink(repo.vfs.join(f)) - afterresolvedstates = [ ('graftstate', _('hg graft --continue')), diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -618,7 +618,7 @@ if date: opts['date'] = dateutil.parsedate(date) - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) cmdutil.bailifchanged(repo) node = scmutil.revsingle(repo, rev).node() @@ -847,7 +847,7 @@ """common used update sequence""" if noupdate: return - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) cmdutil.bailifchanged(repo) return hg.clean(repo, node, show_stats=show_stats) @@ -1664,7 +1664,7 @@ # Let --subrepos on the command line override config setting. ui.setconfig('ui', 'commitsubrepos', True, 'commit') - cmdutil.checkunfinished(repo, commit=True) + statemod.checkunfinished(repo, commit=True) branch = repo[None].branch() bheads = repo.branchheads(branch) @@ -1699,7 +1699,7 @@ # Note: eventually this guard will be removed. Please do not expect # this behavior to remain. if not obsolete.isenabled(repo, obsolete.createmarkersopt): - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) node = cmdutil.amend(ui, repo, old, extra, pats, opts) if node == old.node(): @@ -2482,7 +2482,7 @@ else: if not revs: raise error.Abort(_('no revisions specified')) - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) cmdutil.bailifchanged(repo) revs = scmutil.revrange(repo, revs) @@ -3484,7 +3484,7 @@ with repo.wlock(): if update: - cmdutil.checkunfinished(repo) + statemod.checkunfinished(repo) if (exact or not opts.get('force')): cmdutil.bailifchanged(repo) @@ -6147,8 +6147,7 @@ updatecheck = 'none' with repo.wlock(): - cmdutil.clearunfinished(repo) - + statemod.clearunfinished(repo) if date: rev = cmdutil.finddate(ui, repo, date) diff --git a/mercurial/state.py b/mercurial/state.py --- a/mercurial/state.py +++ b/mercurial/state.py @@ -19,6 +19,8 @@ from __future__ import absolute_import +from .i18n import _ + from . import ( error, util, @@ -85,3 +87,44 @@ def exists(self): """check whether the state file exists or not""" return self._repo.vfs.exists(self.fname) + +# A list of state files kept by multistep operations like graft. +# Since graft cannot be aborted, it is considered 'clearable' by update. +# note: bisect is intentionally excluded +# (state file, clearable, allowcommit, error, hint) +unfinishedstates = [ + ('graftstate', True, False, _('graft in progress'), + _("use 'hg graft --continue' or 'hg graft --stop' to stop")), + ('updatestate', True, False, _('last update was interrupted'), + _("use 'hg update' to get a consistent checkout")) + ] + +def checkunfinished(repo, commit=False): + '''Look for an unfinished multistep operation, like graft, and abort + if found. It's probably good to check this right before + bailifchanged(). + ''' + # Check for non-clearable states first, so things like rebase will take + # precedence over update. + for f, clearable, allowcommit, msg, hint in unfinishedstates: + if clearable or (commit and allowcommit): + continue + if repo.vfs.exists(f): + raise error.Abort(msg, hint=hint) + + for f, clearable, allowcommit, msg, hint in unfinishedstates: + if not clearable or (commit and allowcommit): + continue + if repo.vfs.exists(f): + raise error.Abort(msg, hint=hint) + +def clearunfinished(repo): + '''Check for unfinished operations (as above), and clear the ones + that are clearable. + ''' + for f, clearable, allowcommit, msg, hint in unfinishedstates: + if not clearable and repo.vfs.exists(f): + raise error.Abort(msg, hint=hint) + for f, clearable, allowcommit, msg, hint in unfinishedstates: + if clearable and repo.vfs.exists(f): + util.unlink(repo.vfs.join(f))