This adds support of the new class state.statecheck
throughout core and extensions. This also removes the
previous method cmdutil.unfinishedstates and its API.
The results are shown in tests.
| durin42 | |
| martinvonz |
| hg-reviewers |
This adds support of the new class state.statecheck
throughout core and extensions. This also removes the
previous method cmdutil.unfinishedstates and its API.
The results are shown in tests.
| Lint Skipped |
| Unit Tests Skipped |
| tests/test-histedit-no-change.t | ||
|---|---|---|
| 171 | Could your leave this change for a separate patch at the end (as I said before)? We try to separate refactoring from functional changes. | |
@martinvonz Doing that would be kind of difficult because these changes are not due to refactoring but due to statecheck.hint() which is a unified function for generating hint messages. If I change the messages in accordance to cmdutil.unfinishedstates then this problem will be there in the in integration of STATES. If you still want it I can do that by removing statecheck.hint() completely and getting the messages from cmdutil.py. So should I do that ?
| Path | Packages | |||
|---|---|---|---|---|
| M | hgext/absorb.py (3 lines) | |||
| M | hgext/fix.py (3 lines) | |||
| M | hgext/histedit.py (9 lines) | |||
| M | hgext/phabricator.py (3 lines) | |||
| M | hgext/rebase.py (11 lines) | |||
| M | hgext/record.py (3 lines) | |||
| M | hgext/shelve.py (11 lines) | |||
| M | hgext/strip.py (3 lines) | |||
| M | hgext/transplant.py (8 lines) | |||
| M | mercurial/cmdutil.py (44 lines) | |||
| M | mercurial/commands.py (15 lines) | |||
| M | tests/test-absorb-unfinished.t (3 lines) | |||
| M | tests/test-fix.t (3 lines) | |||
| M | tests/test-graft.t (4 lines) | |||
| M | tests/test-histedit-arguments.t (3 lines) | |||
| M | tests/test-histedit-edit.t (9 lines) | |||
| M | tests/test-histedit-no-change.t (3 lines) | |||
| M | tests/test-qrecord.t (5 lines) | |||
| M | tests/test-rebase-abort.t (15 lines) | |||
| M | tests/test-rebase-obsolete.t (3 lines) | |||
| M | tests/test-rebase-pull.t (3 lines) | |||
| M | tests/test-shelve.t (10 lines) | |||
| M | tests/test-transplant.t (3 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| 454a39e54ad6 | ab362e2ac839 | Taapas Agrawal | Jun 7 2019, 11:16 AM |
| Status | Author | Revision | |
|---|---|---|---|
| Abandoned | taapas1128 | ||
| Abandoned | taapas1128 | ||
| Abandoned | taapas1128 | ||
| Abandoned | taapas1128 |
| mdiff, | mdiff, | ||||
| node, | node, | ||||
| obsolete, | obsolete, | ||||
| patch, | patch, | ||||
| phases, | phases, | ||||
| pycompat, | pycompat, | ||||
| registrar, | registrar, | ||||
| scmutil, | scmutil, | ||||
| state as statemod, | |||||
| util, | util, | ||||
| ) | ) | ||||
| from mercurial.utils import ( | from mercurial.utils import ( | ||||
| stringutil, | stringutil, | ||||
| ) | ) | ||||
| # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||||
| # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | ||||
| immediately. | immediately. | ||||
| Returns 0 on success, 1 if all chunks were ignored and nothing amended. | Returns 0 on success, 1 if all chunks were ignored and nothing amended. | ||||
| """ | """ | ||||
| opts = pycompat.byteskwargs(opts) | opts = pycompat.byteskwargs(opts) | ||||
| with repo.wlock(), repo.lock(): | with repo.wlock(), repo.lock(): | ||||
| if not opts['dry_run']: | if not opts['dry_run']: | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| state = absorb(ui, repo, pats=pats, opts=opts) | state = absorb(ui, repo, pats=pats, opts=opts) | ||||
| if sum(s[0] for s in state.chunkstats.values()) == 0: | if sum(s[0] for s in state.chunkstats.values()) == 0: | ||||
| return 1 | return 1 | ||||
| copies, | copies, | ||||
| error, | error, | ||||
| mdiff, | mdiff, | ||||
| merge, | merge, | ||||
| obsolete, | obsolete, | ||||
| pycompat, | pycompat, | ||||
| registrar, | registrar, | ||||
| scmutil, | scmutil, | ||||
| state as statemod, | |||||
| util, | util, | ||||
| worker, | worker, | ||||
| ) | ) | ||||
| # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||||
| # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | ||||
| # be specifying the version(s) of Mercurial they are tested with, or | # be specifying the version(s) of Mercurial they are tested with, or | ||||
| # leave the attribute unspecified. | # leave the attribute unspecified. | ||||
| return workqueue, numitems | return workqueue, numitems | ||||
| def getrevstofix(ui, repo, opts): | def getrevstofix(ui, repo, opts): | ||||
| """Returns the set of revision numbers that should be fixed""" | """Returns the set of revision numbers that should be fixed""" | ||||
| revs = set(scmutil.revrange(repo, opts['rev'])) | revs = set(scmutil.revrange(repo, opts['rev'])) | ||||
| for rev in revs: | for rev in revs: | ||||
| checkfixablectx(ui, repo, repo[rev]) | checkfixablectx(ui, repo, repo[rev]) | ||||
| if revs: | if revs: | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| checknodescendants(repo, revs) | checknodescendants(repo, revs) | ||||
| if opts.get('working_dir'): | if opts.get('working_dir'): | ||||
| revs.add(wdirrev) | revs.add(wdirrev) | ||||
| if list(merge.mergestate.read(repo).unresolved()): | if list(merge.mergestate.read(repo).unresolved()): | ||||
| raise error.Abort('unresolved conflicts', hint="use 'hg resolve'") | raise error.Abort('unresolved conflicts', hint="use 'hg resolve'") | ||||
| if not revs: | if not revs: | ||||
| raise error.Abort( | raise error.Abort( | ||||
| 'no changesets specified', hint='use --rev or --working-dir') | 'no changesets specified', hint='use --rev or --working-dir') | ||||
| raise error.Abort(_("Python curses library required")) | raise error.Abort(_("Python curses library required")) | ||||
| # disable color | # disable color | ||||
| ui._colormode = None | ui._colormode = None | ||||
| try: | try: | ||||
| keep = opts.get('keep') | keep = opts.get('keep') | ||||
| revs = opts.get('rev', [])[:] | revs = opts.get('rev', [])[:] | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| cmdutil.bailifchanged(repo) | cmdutil.bailifchanged(repo) | ||||
| if os.path.exists(os.path.join(repo.path, 'histedit-state')): | if os.path.exists(os.path.join(repo.path, 'histedit-state')): | ||||
| raise error.Abort(_('history edit already in progress, try ' | raise error.Abort(_('history edit already in progress, try ' | ||||
| '--continue or --abort')) | '--continue or --abort')) | ||||
| revs.extend(freeargs) | revs.extend(freeargs) | ||||
| if not revs: | if not revs: | ||||
| defaultrev = destutil.desthistedit(ui, repo) | defaultrev = destutil.desthistedit(ui, repo) | ||||
| state.actions = actions | state.actions = actions | ||||
| state.write() | state.write() | ||||
| def _newhistedit(ui, repo, state, revs, freeargs, opts): | def _newhistedit(ui, repo, state, revs, freeargs, opts): | ||||
| outg = opts.get('outgoing') | outg = opts.get('outgoing') | ||||
| rules = opts.get('commands', '') | rules = opts.get('commands', '') | ||||
| force = opts.get('force') | force = opts.get('force') | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| cmdutil.bailifchanged(repo) | cmdutil.bailifchanged(repo) | ||||
| topmost = repo.dirstate.p1() | topmost = repo.dirstate.p1() | ||||
| if outg: | if outg: | ||||
| if freeargs: | if freeargs: | ||||
| remote = freeargs[0] | remote = freeargs[0] | ||||
| else: | else: | ||||
| remote = None | remote = None | ||||
| if state.actions: | if state.actions: | ||||
| # i18n: column positioning for "hg summary" | # i18n: column positioning for "hg summary" | ||||
| ui.write(_('hist: %s (histedit --continue)\n') % | ui.write(_('hist: %s (histedit --continue)\n') % | ||||
| (ui.label(_('%d remaining'), 'histedit.remaining') % | (ui.label(_('%d remaining'), 'histedit.remaining') % | ||||
| len(state.actions))) | len(state.actions))) | ||||
| def extsetup(ui): | def extsetup(ui): | ||||
| cmdutil.summaryhooks.add('histedit', summaryhook) | cmdutil.summaryhooks.add('histedit', summaryhook) | ||||
| cmdutil.unfinishedstates.append( | statemod.unfinishedstates.append(statemod.statecheck('histedit', | ||||
| ['histedit-state', False, True, _('histedit in progress'), | 'histedit-state', clearable=False, allowcommit=True, stopflag=False)) | ||||
| _("use 'hg histedit --continue' or 'hg histedit --abort'")]) | |||||
| cmdutil.afterresolvedstates.append( | cmdutil.afterresolvedstates.append( | ||||
| ['histedit-state', _('hg histedit --continue')]) | ['histedit-state', _('hg histedit --continue')]) | ||||
| obsutil, | obsutil, | ||||
| parser, | parser, | ||||
| patch, | patch, | ||||
| phases, | phases, | ||||
| pycompat, | pycompat, | ||||
| registrar, | registrar, | ||||
| scmutil, | scmutil, | ||||
| smartset, | smartset, | ||||
| state as statemod, | |||||
| tags, | tags, | ||||
| templatefilters, | templatefilters, | ||||
| templateutil, | templateutil, | ||||
| url as urlmod, | url as urlmod, | ||||
| util, | util, | ||||
| ) | ) | ||||
| from mercurial.utils import ( | from mercurial.utils import ( | ||||
| procutil, | procutil, | ||||
| """ | """ | ||||
| opts = pycompat.byteskwargs(opts) | opts = pycompat.byteskwargs(opts) | ||||
| revs = list(revs) + opts.get(b'rev', []) | revs = list(revs) + opts.get(b'rev', []) | ||||
| revs = scmutil.revrange(repo, revs) | revs = scmutil.revrange(repo, revs) | ||||
| if not revs: | if not revs: | ||||
| raise error.Abort(_(b'phabsend requires at least one changeset')) | raise error.Abort(_(b'phabsend requires at least one changeset')) | ||||
| if opts.get(b'amend'): | if opts.get(b'amend'): | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| # {newnode: (oldnode, olddiff, olddrev} | # {newnode: (oldnode, olddiff, olddrev} | ||||
| oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs]) | oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs]) | ||||
| confirm = ui.configbool(b'phabsend', b'confirm') | confirm = ui.configbool(b'phabsend', b'confirm') | ||||
| confirm |= bool(opts.get(b'confirm')) | confirm |= bool(opts.get(b'confirm')) | ||||
| if confirm: | if confirm: | ||||
| confirmed = _confirmbeforesend(repo, revs, oldmap) | confirmed = _confirmbeforesend(repo, revs, oldmap) | ||||
| if srcf and basef: | if srcf and basef: | ||||
| raise error.Abort(_('cannot specify both a source and a base')) | raise error.Abort(_('cannot specify both a source and a base')) | ||||
| if revf and basef: | if revf and basef: | ||||
| raise error.Abort(_('cannot specify both a revision and a base')) | raise error.Abort(_('cannot specify both a revision and a base')) | ||||
| if revf and srcf: | if revf and srcf: | ||||
| raise error.Abort(_('cannot specify both a revision and a source')) | raise error.Abort(_('cannot specify both a revision and a source')) | ||||
| if not inmemory: | if not inmemory: | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| cmdutil.bailifchanged(repo) | cmdutil.bailifchanged(repo) | ||||
| if ui.configbool('commands', 'rebase.requiredest') and not destf: | if ui.configbool('commands', 'rebase.requiredest') and not destf: | ||||
| raise error.Abort(_('you must specify a destination'), | raise error.Abort(_('you must specify a destination'), | ||||
| hint=_('use: hg rebase -d REV')) | hint=_('use: hg rebase -d REV')) | ||||
| dest = None | dest = None | ||||
| ('+'.join(bytes(repo[r]) for r in base), dest)) | ('+'.join(bytes(repo[r]) for r in base), dest)) | ||||
| return None | return None | ||||
| rebasingwcp = repo['.'].rev() in rebaseset | rebasingwcp = repo['.'].rev() in rebaseset | ||||
| ui.log("rebase", "rebasing working copy parent: %r\n", rebasingwcp, | ui.log("rebase", "rebasing working copy parent: %r\n", rebasingwcp, | ||||
| rebase_rebasing_wcp=rebasingwcp) | rebase_rebasing_wcp=rebasingwcp) | ||||
| if inmemory and rebasingwcp: | if inmemory and rebasingwcp: | ||||
| # Check these since we did not before. | # Check these since we did not before. | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| cmdutil.bailifchanged(repo) | cmdutil.bailifchanged(repo) | ||||
| if not destf: | if not destf: | ||||
| dest = repo[_destrebase(repo, rebaseset, destspace=destspace)] | dest = repo[_destrebase(repo, rebaseset, destspace=destspace)] | ||||
| destf = bytes(dest) | destf = bytes(dest) | ||||
| allsrc = revsetlang.formatspec('%ld', rebaseset) | allsrc = revsetlang.formatspec('%ld', rebaseset) | ||||
| alias = {'ALLSRC': allsrc} | alias = {'ALLSRC': allsrc} | ||||
| raise error.Abort(msg, hint=hint) | raise error.Abort(msg, hint=hint) | ||||
| with repo.wlock(), repo.lock(): | with repo.wlock(), repo.lock(): | ||||
| if opts.get(r'update'): | if opts.get(r'update'): | ||||
| del opts[r'update'] | del opts[r'update'] | ||||
| ui.debug('--update and --rebase are not compatible, ignoring ' | ui.debug('--update and --rebase are not compatible, ignoring ' | ||||
| 'the update flag\n') | 'the update flag\n') | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| cmdutil.bailifchanged(repo, hint=_('cannot pull with rebase: ' | cmdutil.bailifchanged(repo, hint=_('cannot pull with rebase: ' | ||||
| 'please commit or shelve your changes first')) | 'please commit or shelve your changes first')) | ||||
| revsprepull = len(repo) | revsprepull = len(repo) | ||||
| origpostincoming = commands.postincoming | origpostincoming = commands.postincoming | ||||
| def _dummy(*args, **kwargs): | def _dummy(*args, **kwargs): | ||||
| pass | pass | ||||
| commands.postincoming = _dummy | commands.postincoming = _dummy | ||||
| def uisetup(ui): | def uisetup(ui): | ||||
| #Replace pull with a decorator to provide --rebase option | #Replace pull with a decorator to provide --rebase option | ||||
| entry = extensions.wrapcommand(commands.table, 'pull', pullrebase) | entry = extensions.wrapcommand(commands.table, 'pull', pullrebase) | ||||
| entry[1].append(('', 'rebase', None, | entry[1].append(('', 'rebase', None, | ||||
| _("rebase working directory to branch head"))) | _("rebase working directory to branch head"))) | ||||
| entry[1].append(('t', 'tool', '', | entry[1].append(('t', 'tool', '', | ||||
| _("specify merge tool for rebase"))) | _("specify merge tool for rebase"))) | ||||
| cmdutil.summaryhooks.add('rebase', summaryhook) | cmdutil.summaryhooks.add('rebase', summaryhook) | ||||
| cmdutil.unfinishedstates.append( | statemod.unfinishedstates.append(statemod.statecheck('rebase', | ||||
| ['rebasestate', False, False, _('rebase in progress'), | 'rebasestate', clearable=False, allowcommit=False, stopflag=False)) | ||||
| _("use 'hg rebase --continue' or 'hg rebase --abort'")]) | |||||
| cmdutil.afterresolvedstates.append( | cmdutil.afterresolvedstates.append( | ||||
| ['rebasestate', _('hg rebase --continue')]) | ['rebasestate', _('hg rebase --continue')]) | ||||
| from mercurial.i18n import _ | from mercurial.i18n import _ | ||||
| from mercurial import ( | from mercurial import ( | ||||
| cmdutil, | cmdutil, | ||||
| commands, | commands, | ||||
| error, | error, | ||||
| extensions, | extensions, | ||||
| registrar, | registrar, | ||||
| state as statemod, | |||||
| ) | ) | ||||
| cmdtable = {} | cmdtable = {} | ||||
| command = registrar.command(cmdtable) | command = registrar.command(cmdtable) | ||||
| # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||||
| # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | ||||
| # be specifying the version(s) of Mercurial they are tested with, or | # be specifying the version(s) of Mercurial they are tested with, or | ||||
| # leave the attribute unspecified. | # leave the attribute unspecified. | ||||
| repo.mq.checkpatchname(patch) | repo.mq.checkpatchname(patch) | ||||
| def committomq(ui, repo, *pats, **opts): | def committomq(ui, repo, *pats, **opts): | ||||
| opts[r'checkname'] = False | opts[r'checkname'] = False | ||||
| mq.new(ui, repo, patch, *pats, **opts) | mq.new(ui, repo, patch, *pats, **opts) | ||||
| overrides = {('experimental', 'crecord'): False} | overrides = {('experimental', 'crecord'): False} | ||||
| with ui.configoverride(overrides, 'record'): | with ui.configoverride(overrides, 'record'): | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| cmdutil.dorecord(ui, repo, committomq, cmdsuggest, False, | cmdutil.dorecord(ui, repo, committomq, cmdsuggest, False, | ||||
| cmdutil.recordfilter, *pats, **opts) | cmdutil.recordfilter, *pats, **opts) | ||||
| def qnew(origfn, ui, repo, patch, *args, **opts): | def qnew(origfn, ui, repo, patch, *args, **opts): | ||||
| if opts[r'interactive']: | if opts[r'interactive']: | ||||
| return _qrecord(None, ui, repo, patch, *args, **opts) | return _qrecord(None, ui, repo, patch, *args, **opts) | ||||
| return origfn(ui, repo, patch, *args, **opts) | return origfn(ui, repo, patch, *args, **opts) | ||||
| merge, | merge, | ||||
| node as nodemod, | node as nodemod, | ||||
| patch, | patch, | ||||
| phases, | phases, | ||||
| pycompat, | pycompat, | ||||
| registrar, | registrar, | ||||
| repair, | repair, | ||||
| scmutil, | scmutil, | ||||
| state as statemod, | |||||
| templatefilters, | templatefilters, | ||||
| util, | util, | ||||
| vfs as vfsmod, | vfs as vfsmod, | ||||
| ) | ) | ||||
| from . import ( | from . import ( | ||||
| rebase, | rebase, | ||||
| ) | ) | ||||
| if phases.supportinternal(repo): | if phases.supportinternal(repo): | ||||
| tr.close() | tr.close() | ||||
| else: | else: | ||||
| _aborttransaction(repo, tr) | _aborttransaction(repo, tr) | ||||
| def createcmd(ui, repo, pats, opts): | def createcmd(ui, repo, pats, opts): | ||||
| """subcommand that creates a new shelve""" | """subcommand that creates a new shelve""" | ||||
| with repo.wlock(): | with repo.wlock(): | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| return _docreatecmd(ui, repo, pats, opts) | return _docreatecmd(ui, repo, pats, opts) | ||||
| def _docreatecmd(ui, repo, pats, opts): | def _docreatecmd(ui, repo, pats, opts): | ||||
| wctx = repo[None] | wctx = repo[None] | ||||
| parents = wctx.parents() | parents = wctx.parents() | ||||
| if len(parents) > 1: | if len(parents) > 1: | ||||
| raise error.Abort(_('cannot shelve while merging')) | raise error.Abort(_('cannot shelve while merging')) | ||||
| parent = parents[0] | parent = parents[0] | ||||
| with repo.wlock(): | with repo.wlock(): | ||||
| return _dounshelve(ui, repo, *shelved, **opts) | return _dounshelve(ui, repo, *shelved, **opts) | ||||
| def _dounshelve(ui, repo, *shelved, **opts): | def _dounshelve(ui, repo, *shelved, **opts): | ||||
| opts = pycompat.byteskwargs(opts) | opts = pycompat.byteskwargs(opts) | ||||
| abortf = opts.get('abort') | abortf = opts.get('abort') | ||||
| continuef = opts.get('continue') | continuef = opts.get('continue') | ||||
| if not abortf and not continuef: | if not abortf and not continuef: | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| shelved = list(shelved) | shelved = list(shelved) | ||||
| if opts.get("name"): | if opts.get("name"): | ||||
| shelved.append(opts["name"]) | shelved.append(opts["name"]) | ||||
| if abortf or continuef: | if abortf or continuef: | ||||
| if abortf and continuef: | if abortf and continuef: | ||||
| raise error.Abort(_('cannot use both abort and continue')) | raise error.Abort(_('cannot use both abort and continue')) | ||||
| if shelved: | if shelved: | ||||
| elif checkopt('list'): | elif checkopt('list'): | ||||
| return listcmd(ui, repo, pats, opts) | return listcmd(ui, repo, pats, opts) | ||||
| elif checkopt('patch') or checkopt('stat'): | elif checkopt('patch') or checkopt('stat'): | ||||
| return patchcmds(ui, repo, pats, opts) | return patchcmds(ui, repo, pats, opts) | ||||
| else: | else: | ||||
| return createcmd(ui, repo, pats, opts) | return createcmd(ui, repo, pats, opts) | ||||
| def extsetup(ui): | def extsetup(ui): | ||||
| cmdutil.unfinishedstates.append( | statemod.unfinishedstates.append(statemod.statecheck('unshelve', | ||||
| [shelvedstate._filename, False, False, | shelvedstate._filename, clearable=False, allowcommit=False, stopflag=False)) | ||||
| _('unshelve already in progress'), | |||||
| _("use 'hg unshelve --continue' or 'hg unshelve --abort'")]) | |||||
| cmdutil.afterresolvedstates.append( | cmdutil.afterresolvedstates.append( | ||||
| [shelvedstate._filename, _('hg unshelve --continue')]) | [shelvedstate._filename, _('hg unshelve --continue')]) | ||||
| hg, | hg, | ||||
| lock as lockmod, | lock as lockmod, | ||||
| merge, | merge, | ||||
| node as nodemod, | node as nodemod, | ||||
| pycompat, | pycompat, | ||||
| registrar, | registrar, | ||||
| repair, | repair, | ||||
| scmutil, | scmutil, | ||||
| state as statemod, | |||||
| util, | util, | ||||
| ) | ) | ||||
| nullid = nodemod.nullid | nullid = nodemod.nullid | ||||
| release = lockmod.release | release = lockmod.release | ||||
| cmdtable = {} | cmdtable = {} | ||||
| command = registrar.command(cmdtable) | command = registrar.command(cmdtable) | ||||
| # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||||
| bctx = wctx.p1() | bctx = wctx.p1() | ||||
| for s in sorted(wctx.substate): | for s in sorted(wctx.substate): | ||||
| wctx.sub(s).bailifchanged(True) | wctx.sub(s).bailifchanged(True) | ||||
| if s not in bctx.substate or bctx.sub(s).dirty(): | if s not in bctx.substate or bctx.sub(s).dirty(): | ||||
| inclsubs.append(s) | inclsubs.append(s) | ||||
| return inclsubs | return inclsubs | ||||
| def checklocalchanges(repo, force=False, excsuffix=''): | def checklocalchanges(repo, force=False, excsuffix=''): | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| s = repo.status() | s = repo.status() | ||||
| if not force: | if not force: | ||||
| if s.modified or s.added or s.removed or s.deleted: | if s.modified or s.added or s.removed or s.deleted: | ||||
| _("local changes found") # i18n tool detection | _("local changes found") # i18n tool detection | ||||
| raise error.Abort(_("local changes found" + excsuffix)) | raise error.Abort(_("local changes found" + excsuffix)) | ||||
| if checksubstate(repo): | if checksubstate(repo): | ||||
| _("local changed subrepos found") # i18n tool detection | _("local changed subrepos found") # i18n tool detection | ||||
| raise error.Abort(_("local changed subrepos found" + excsuffix)) | raise error.Abort(_("local changed subrepos found" + excsuffix)) | ||||
| node as nodemod, | node as nodemod, | ||||
| patch, | patch, | ||||
| pycompat, | pycompat, | ||||
| registrar, | registrar, | ||||
| revlog, | revlog, | ||||
| revset, | revset, | ||||
| scmutil, | scmutil, | ||||
| smartset, | smartset, | ||||
| state as statemod, | |||||
| util, | util, | ||||
| vfs as vfsmod, | vfs as vfsmod, | ||||
| ) | ) | ||||
| from mercurial.utils import ( | from mercurial.utils import ( | ||||
| procutil, | procutil, | ||||
| stringutil, | stringutil, | ||||
| ) | ) | ||||
| p1 = repo.dirstate.p1() | p1 = repo.dirstate.p1() | ||||
| if len(repo) > 0 and p1 == revlog.nullid: | if len(repo) > 0 and p1 == revlog.nullid: | ||||
| raise error.Abort(_('no revision checked out')) | raise error.Abort(_('no revision checked out')) | ||||
| if opts.get('continue'): | if opts.get('continue'): | ||||
| if not tp.canresume(): | if not tp.canresume(): | ||||
| raise error.Abort(_('no transplant to continue')) | raise error.Abort(_('no transplant to continue')) | ||||
| else: | else: | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| cmdutil.bailifchanged(repo) | cmdutil.bailifchanged(repo) | ||||
| sourcerepo = opts.get('source') | sourcerepo = opts.get('source') | ||||
| if sourcerepo: | if sourcerepo: | ||||
| peer = hg.peer(repo, opts, ui.expandpath(sourcerepo)) | peer = hg.peer(repo, opts, ui.expandpath(sourcerepo)) | ||||
| heads = pycompat.maplist(peer.lookup, opts.get('branch', ())) | heads = pycompat.maplist(peer.lookup, opts.get('branch', ())) | ||||
| target = set(heads) | target = set(heads) | ||||
| for r in revs: | for r in revs: | ||||
| def kwtransplanted(context, mapping): | def kwtransplanted(context, mapping): | ||||
| """String. The node identifier of the transplanted | """String. The node identifier of the transplanted | ||||
| changeset if any.""" | changeset if any.""" | ||||
| ctx = context.resource(mapping, 'ctx') | ctx = context.resource(mapping, 'ctx') | ||||
| n = ctx.extra().get('transplant_source') | n = ctx.extra().get('transplant_source') | ||||
| return n and nodemod.hex(n) or '' | return n and nodemod.hex(n) or '' | ||||
| def extsetup(ui): | def extsetup(ui): | ||||
| cmdutil.unfinishedstates.append( | statemod.unfinishedstates.append(statemod.statecheck('transplant', | ||||
| ['transplant/journal', True, False, _('transplant in progress'), | 'transplant/journal', clearable=True, allowcommit=False, stopflag=False)) | ||||
| _("use 'hg transplant --continue' or 'hg update' to abort")]) | |||||
| # tell hggettext to extract docstrings from these functions: | # tell hggettext to extract docstrings from these functions: | ||||
| i18nfunctions = [revsettransplanted, kwtransplanted] | i18nfunctions = [revsettransplanted, kwtransplanted] | ||||
| patch, | patch, | ||||
| pathutil, | pathutil, | ||||
| phases, | phases, | ||||
| pycompat, | pycompat, | ||||
| revlog, | revlog, | ||||
| rewriteutil, | rewriteutil, | ||||
| scmutil, | scmutil, | ||||
| smartset, | smartset, | ||||
| state as statemod, | |||||
| subrepoutil, | subrepoutil, | ||||
| templatekw, | templatekw, | ||||
| templater, | templater, | ||||
| util, | util, | ||||
| vfs as vfsmod, | vfs as vfsmod, | ||||
| ) | ) | ||||
| from .utils import ( | from .utils import ( | ||||
| After the actual job is done by non-interactive command, the | After the actual job is done by non-interactive command, the | ||||
| working directory is restored to its original state. | working directory is restored to its original state. | ||||
| In the end we'll record interesting changes, and everything else | In the end we'll record interesting changes, and everything else | ||||
| will be left in place, so the user can continue working. | will be left in place, so the user can continue working. | ||||
| """ | """ | ||||
| checkunfinished(repo, commit=True) | statemod.checkunfinished(repo, commit=True) | ||||
| wctx = repo[None] | wctx = repo[None] | ||||
| merge = len(wctx.parents()) > 1 | merge = len(wctx.parents()) > 1 | ||||
| if merge: | if merge: | ||||
| raise error.Abort(_('cannot partially commit a merge ' | raise error.Abort(_('cannot partially commit a merge ' | ||||
| '(use "hg commit" instead)')) | '(use "hg commit" instead)')) | ||||
| def fail(f, msg): | def fail(f, msg): | ||||
| raise error.Abort('%s: %s' % (f, msg)) | raise error.Abort('%s: %s' % (f, msg)) | ||||
| # functions should return tuple of booleans below, if 'changes' is None: | # functions should return tuple of booleans below, if 'changes' is None: | ||||
| # (whether-incomings-are-needed, whether-outgoings-are-needed) | # (whether-incomings-are-needed, whether-outgoings-are-needed) | ||||
| # | # | ||||
| # otherwise, 'changes' is a tuple of tuples below: | # otherwise, 'changes' is a tuple of tuples below: | ||||
| # - (sourceurl, sourcebranch, sourcepeer, incoming) | # - (sourceurl, sourcebranch, sourcepeer, incoming) | ||||
| # - (desturl, destbranch, destpeer, outgoing) | # - (desturl, destbranch, destpeer, outgoing) | ||||
| summaryremotehooks = util.hooks() | 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 = [ | afterresolvedstates = [ | ||||
| ('graftstate', | ('graftstate', | ||||
| _('hg graft --continue')), | _('hg graft --continue')), | ||||
| ] | ] | ||||
| def howtocontinue(repo): | def howtocontinue(repo): | ||||
| '''Check for an unfinished operation and return the command to finish | '''Check for an unfinished operation and return the command to finish | ||||
| it. | it. | ||||
| if not rev: | if not rev: | ||||
| raise error.Abort(_("please specify a revision to backout")) | raise error.Abort(_("please specify a revision to backout")) | ||||
| date = opts.get('date') | date = opts.get('date') | ||||
| if date: | if date: | ||||
| opts['date'] = dateutil.parsedate(date) | opts['date'] = dateutil.parsedate(date) | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| cmdutil.bailifchanged(repo) | cmdutil.bailifchanged(repo) | ||||
| node = scmutil.revsingle(repo, rev).node() | node = scmutil.revsingle(repo, rev).node() | ||||
| op1, op2 = repo.dirstate.parents() | op1, op2 = repo.dirstate.parents() | ||||
| if not repo.changelog.isancestor(node, op1): | if not repo.changelog.isancestor(node, op1): | ||||
| raise error.Abort(_('cannot backout change that is not an ancestor')) | raise error.Abort(_('cannot backout change that is not an ancestor')) | ||||
| p1, p2 = repo.changelog.parents(node) | p1, p2 = repo.changelog.parents(node) | ||||
| hbisect.save_state(repo, state) | hbisect.save_state(repo, state) | ||||
| if not (state['good'] and state['bad']): | if not (state['good'] and state['bad']): | ||||
| return | return | ||||
| def mayupdate(repo, node, show_stats=True): | def mayupdate(repo, node, show_stats=True): | ||||
| """common used update sequence""" | """common used update sequence""" | ||||
| if noupdate: | if noupdate: | ||||
| return | return | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| cmdutil.bailifchanged(repo) | cmdutil.bailifchanged(repo) | ||||
| return hg.clean(repo, node, show_stats=show_stats) | return hg.clean(repo, node, show_stats=show_stats) | ||||
| displayer = logcmdutil.changesetdisplayer(ui, repo, {}) | displayer = logcmdutil.changesetdisplayer(ui, repo, {}) | ||||
| if command: | if command: | ||||
| changesets = 1 | changesets = 1 | ||||
| if noupdate: | if noupdate: | ||||
| opts = pycompat.byteskwargs(opts) | opts = pycompat.byteskwargs(opts) | ||||
| if opts.get('subrepos'): | if opts.get('subrepos'): | ||||
| if opts.get('amend'): | if opts.get('amend'): | ||||
| raise error.Abort(_('cannot amend with --subrepos')) | raise error.Abort(_('cannot amend with --subrepos')) | ||||
| # Let --subrepos on the command line override config setting. | # Let --subrepos on the command line override config setting. | ||||
| ui.setconfig('ui', 'commitsubrepos', True, 'commit') | ui.setconfig('ui', 'commitsubrepos', True, 'commit') | ||||
| cmdutil.checkunfinished(repo, commit=True) | statemod.checkunfinished(repo, commit=True) | ||||
| branch = repo[None].branch() | branch = repo[None].branch() | ||||
| bheads = repo.branchheads(branch) | bheads = repo.branchheads(branch) | ||||
| extra = {} | extra = {} | ||||
| if opts.get('close_branch'): | if opts.get('close_branch'): | ||||
| extra['close'] = '1' | extra['close'] = '1' | ||||
| # Currently histedit gets confused if an amend happens while histedit | # Currently histedit gets confused if an amend happens while histedit | ||||
| # is in progress. Since we have a checkunfinished command, we are | # is in progress. Since we have a checkunfinished command, we are | ||||
| # temporarily honoring it. | # temporarily honoring it. | ||||
| # | # | ||||
| # Note: eventually this guard will be removed. Please do not expect | # Note: eventually this guard will be removed. Please do not expect | ||||
| # this behavior to remain. | # this behavior to remain. | ||||
| if not obsolete.isenabled(repo, obsolete.createmarkersopt): | if not obsolete.isenabled(repo, obsolete.createmarkersopt): | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| node = cmdutil.amend(ui, repo, old, extra, pats, opts) | node = cmdutil.amend(ui, repo, old, extra, pats, opts) | ||||
| if node == old.node(): | if node == old.node(): | ||||
| ui.status(_("nothing changed\n")) | ui.status(_("nothing changed\n")) | ||||
| return 1 | return 1 | ||||
| else: | else: | ||||
| def commitfunc(ui, repo, message, match, opts): | def commitfunc(ui, repo, message, match, opts): | ||||
| overrides = {} | overrides = {} | ||||
| opts['no_commit'] = statedata.get('no_commit') | opts['no_commit'] = statedata.get('no_commit') | ||||
| nodes = statedata['nodes'] | nodes = statedata['nodes'] | ||||
| revs = [repo[node].rev() for node in nodes] | revs = [repo[node].rev() for node in nodes] | ||||
| else: | else: | ||||
| cmdutil.wrongtooltocontinue(repo, _('graft')) | cmdutil.wrongtooltocontinue(repo, _('graft')) | ||||
| else: | else: | ||||
| if not revs: | if not revs: | ||||
| raise error.Abort(_('no revisions specified')) | raise error.Abort(_('no revisions specified')) | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| cmdutil.bailifchanged(repo) | cmdutil.bailifchanged(repo) | ||||
| revs = scmutil.revrange(repo, revs) | revs = scmutil.revrange(repo, revs) | ||||
| skipped = set() | skipped = set() | ||||
| if basectx is None: | if basectx is None: | ||||
| # check for merges | # check for merges | ||||
| for rev in repo.revs('%ld and merge()', revs): | for rev in repo.revs('%ld and merge()', revs): | ||||
| ui.warn(_('skipping ungraftable merge revision %d\n') % rev) | ui.warn(_('skipping ungraftable merge revision %d\n') % rev) | ||||
| raise error.Abort(_('cannot use --exact with --prefix')) | raise error.Abort(_('cannot use --exact with --prefix')) | ||||
| base = opts["base"] | base = opts["base"] | ||||
| msgs = [] | msgs = [] | ||||
| ret = 0 | ret = 0 | ||||
| with repo.wlock(): | with repo.wlock(): | ||||
| if update: | if update: | ||||
| cmdutil.checkunfinished(repo) | statemod.checkunfinished(repo) | ||||
| if (exact or not opts.get('force')): | if (exact or not opts.get('force')): | ||||
| cmdutil.bailifchanged(repo) | cmdutil.bailifchanged(repo) | ||||
| if not opts.get('no_commit'): | if not opts.get('no_commit'): | ||||
| lock = repo.lock | lock = repo.lock | ||||
| tr = lambda: repo.transaction('import') | tr = lambda: repo.transaction('import') | ||||
| dsguard = util.nullcontextmanager | dsguard = util.nullcontextmanager | ||||
| else: | else: | ||||
| updatecheck = None | updatecheck = None | ||||
| if check: | if check: | ||||
| updatecheck = 'abort' | updatecheck = 'abort' | ||||
| elif merge: | elif merge: | ||||
| updatecheck = 'none' | updatecheck = 'none' | ||||
| with repo.wlock(): | with repo.wlock(): | ||||
| cmdutil.clearunfinished(repo) | statemod.clearunfinished(repo) | ||||
| if date: | if date: | ||||
| rev = cmdutil.finddate(ui, repo, date) | rev = cmdutil.finddate(ui, repo, date) | ||||
| # if we defined a bookmark, we have to remember the original name | # if we defined a bookmark, we have to remember the original name | ||||
| brev = rev | brev = rev | ||||
| if rev: | if rev: | ||||
| repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn') | repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn') | ||||
| ctx = scmutil.revsingle(repo, rev, default=None) | ctx = scmutil.revsingle(repo, rev, default=None) | ||||
| rebasing 1:c3b6dc0e177a "foo 2" (tip) | rebasing 1:c3b6dc0e177a "foo 2" (tip) | ||||
| merging foo.whole | merging foo.whole | ||||
| warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark') | warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark') | ||||
| unresolved conflicts (see hg resolve, then hg rebase --continue) | unresolved conflicts (see hg resolve, then hg rebase --continue) | ||||
| [1] | [1] | ||||
| $ hg --config extensions.rebase= absorb | $ hg --config extensions.rebase= absorb | ||||
| abort: rebase in progress | abort: rebase in progress | ||||
| (use 'hg rebase --continue' or 'hg rebase --abort') | (To continue: hg rebase --continue | ||||
| To abort: hg rebase --abort) | |||||
| [255] | [255] | ||||
| $ hg --config extensions.rebase= fix --working-dir | $ hg --config extensions.rebase= fix --working-dir | ||||
| abort: unresolved conflicts | abort: unresolved conflicts | ||||
| (use 'hg resolve') | (use 'hg resolve') | ||||
| [255] | [255] | ||||
| $ hg --config extensions.rebase= fix -r . | $ hg --config extensions.rebase= fix -r . | ||||
| abort: rebase in progress | abort: rebase in progress | ||||
| (use 'hg rebase --continue' or 'hg rebase --abort') | (To continue: hg rebase --continue | ||||
| To abort: hg rebase --abort) | |||||
| [255] | [255] | ||||
| $ cd .. | $ cd .. | ||||
| When fixing a file that was renamed, we should diff against the source of the | When fixing a file that was renamed, we should diff against the source of the | ||||
| rename for incremental fixing and we should correctly reproduce the rename in | rename for incremental fixing and we should correctly reproduce the rename in | ||||
| the replacement revision. | the replacement revision. | ||||
| # To continue: hg graft --continue | # To continue: hg graft --continue | ||||
| # To abort: hg graft --abort | # To abort: hg graft --abort | ||||
| Commit while interrupted should fail: | Commit while interrupted should fail: | ||||
| $ hg ci -m 'commit interrupted graft' | $ hg ci -m 'commit interrupted graft' | ||||
| abort: graft in progress | abort: graft in progress | ||||
| (use 'hg graft --continue' or 'hg graft --stop' to stop) | (To continue: hg graft --continue | ||||
| To abort: hg graft --abort | |||||
| To stop: hg graft --stop) | |||||
| [255] | [255] | ||||
| Abort the graft and try committing: | Abort the graft and try committing: | ||||
| $ hg up -C . | $ hg up -C . | ||||
| 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | ||||
| $ echo c >> e | $ echo c >> e | ||||
| $ hg ci -mtest | $ hg ci -mtest | ||||
| Editing (6f2f0241f119), you may commit or record as needed now. | Editing (6f2f0241f119), you may commit or record as needed now. | ||||
| (hg histedit --continue to resume) | (hg histedit --continue to resume) | ||||
| [1] | [1] | ||||
| $ hg resolve -m --all | $ hg resolve -m --all | ||||
| (no more unresolved files) | (no more unresolved files) | ||||
| continue: hg histedit --continue | continue: hg histedit --continue | ||||
| $ hg commit --amend -m 'reject this fold' | $ hg commit --amend -m 'reject this fold' | ||||
| abort: histedit in progress | abort: histedit in progress | ||||
| (use 'hg histedit --continue' or 'hg histedit --abort') | (To continue: hg histedit --continue | ||||
| To abort: hg histedit --abort) | |||||
| [255] | [255] | ||||
| With markers enabled, histedit does not get confused, and | With markers enabled, histedit does not get confused, and | ||||
| amend should not be blocked by the ongoing histedit. | amend should not be blocked by the ongoing histedit. | ||||
| $ cat >>$HGRCPATH <<EOF | $ cat >>$HGRCPATH <<EOF | ||||
| > [experimental] | > [experimental] | ||||
| > evolution.createmarkers=True | > evolution.createmarkers=True | ||||
| > EOF | > EOF | ||||
| 0 files updated, 0 files merged, 3 files removed, 0 files unresolved | 0 files updated, 0 files merged, 3 files removed, 0 files unresolved | ||||
| Editing (e860deea161a), you may commit or record as needed now. | Editing (e860deea161a), you may commit or record as needed now. | ||||
| (hg histedit --continue to resume) | (hg histedit --continue to resume) | ||||
| try to update and get an error | try to update and get an error | ||||
| $ hg update tip | $ hg update tip | ||||
| abort: histedit in progress | abort: histedit in progress | ||||
| (use 'hg histedit --continue' or 'hg histedit --abort') | (To continue: hg histedit --continue | ||||
| To abort: hg histedit --abort) | |||||
| [255] | [255] | ||||
| edit the plan via the editor | edit the plan via the editor | ||||
| $ cat >> $TESTTMP/editplan.sh <<EOF | $ cat >> $TESTTMP/editplan.sh <<EOF | ||||
| > cat > \$1 <<EOF2 | > cat > \$1 <<EOF2 | ||||
| > drop e860deea161a e | > drop e860deea161a e | ||||
| > drop 652413bf663e f | > drop 652413bf663e f | ||||
| > drop 3c6a8ed2ebe8 g | > drop 3c6a8ed2ebe8 g | ||||
| strip-backup/177f92b77385-0ebe6a8f-histedit.hg | strip-backup/177f92b77385-0ebe6a8f-histedit.hg | ||||
| Go at a random point and try to continue | Go at a random point and try to continue | ||||
| $ hg id -n | $ hg id -n | ||||
| 3+ | 3+ | ||||
| $ hg up 0 | $ hg up 0 | ||||
| abort: histedit in progress | abort: histedit in progress | ||||
| (use 'hg histedit --continue' or 'hg histedit --abort') | (To continue: hg histedit --continue | ||||
| To abort: hg histedit --abort) | |||||
| [255] | [255] | ||||
| Try to delete necessary commit | Try to delete necessary commit | ||||
| $ hg strip -r 652413b | $ hg strip -r 652413b | ||||
| abort: histedit in progress, can't strip 652413bf663e | abort: histedit in progress, can't strip 652413bf663e | ||||
| [255] | [255] | ||||
| commit, then edit the revision | commit, then edit the revision | ||||
| $ hg ci -m 'wat' | $ hg ci -m 'wat' | ||||
| created new head | created new head | ||||
| $ echo a > e | $ echo a > e | ||||
| qnew should fail while we're in the middle of the edit step | qnew should fail while we're in the middle of the edit step | ||||
| $ hg --config extensions.mq= qnew please-fail | $ hg --config extensions.mq= qnew please-fail | ||||
| abort: histedit in progress | abort: histedit in progress | ||||
| (use 'hg histedit --continue' or 'hg histedit --abort') | (To continue: hg histedit --continue | ||||
| To abort: hg histedit --abort) | |||||
| [255] | [255] | ||||
| $ HGEDITOR='echo foobaz > ' hg histedit --continue 2>&1 | fixbundle | $ HGEDITOR='echo foobaz > ' hg histedit --continue 2>&1 | fixbundle | ||||
| $ hg log --graph | $ hg log --graph | ||||
| @ changeset: 6:b5f70786f9b0 | @ changeset: 6:b5f70786f9b0 | ||||
| | tag: tip | | tag: tip | ||||
| | user: test | | user: test | ||||
| | date: Thu Jan 01 00:00:00 1970 +0000 | | date: Thu Jan 01 00:00:00 1970 +0000 | ||||
| > y | > y | ||||
| > y | > y | ||||
| > n | > n | ||||
| > y | > y | ||||
| > y | > y | ||||
| > n | > n | ||||
| > EOF | > EOF | ||||
| abort: histedit in progress | abort: histedit in progress | ||||
| (use 'hg histedit --continue' or 'hg histedit --abort') | (To continue: hg histedit --continue | ||||
| To abort: hg histedit --abort) | |||||
| [255] | [255] | ||||
| $ hg up -C 0 # user does other stuff in the repo | $ hg up -C 0 # user does other stuff in the repo | ||||
| 0 files updated, 0 files merged, 1 files removed, 0 files unresolved | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved | ||||
| $ mv rebasestate .hg/ # user upgrades to 2.7 | $ mv rebasestate .hg/ # user upgrades to 2.7 | ||||
| $ echo new > a | $ echo new > a | ||||
| $ hg up 1 # user gets an error saying to run hg rebase --abort | $ hg up 1 # user gets an error saying to run hg rebase --abort | ||||
| abort: rebase in progress | abort: rebase in progress | ||||
| (use 'hg rebase --continue' or 'hg rebase --abort') | (To continue: hg rebase --continue | ||||
| To abort: hg rebase --abort) | |||||
| [255] | [255] | ||||
| $ cat a | $ cat a | ||||
| new | new | ||||
| $ hg rebase --abort | $ hg rebase --abort | ||||
| rebase aborted | rebase aborted | ||||
| $ cat a | $ cat a | ||||
| new | new | ||||
| .hg/merge/state | .hg/merge/state | ||||
| .hg/rebasestate | .hg/rebasestate | ||||
| .hg/undo.backup.dirstate | .hg/undo.backup.dirstate | ||||
| .hg/undo.dirstate | .hg/undo.dirstate | ||||
| .hg/updatestate | .hg/updatestate | ||||
| $ hg rebase -s 3 -d tip | $ hg rebase -s 3 -d tip | ||||
| abort: rebase in progress | abort: rebase in progress | ||||
| (use 'hg rebase --continue' or 'hg rebase --abort') | (To continue: hg rebase --continue | ||||
| To abort: hg rebase --abort) | |||||
| [255] | [255] | ||||
| $ hg up . | $ hg up . | ||||
| abort: rebase in progress | abort: rebase in progress | ||||
| (use 'hg rebase --continue' or 'hg rebase --abort') | (To continue: hg rebase --continue | ||||
| To abort: hg rebase --abort) | |||||
| [255] | [255] | ||||
| $ hg up -C . | $ hg up -C . | ||||
| abort: rebase in progress | abort: rebase in progress | ||||
| (use 'hg rebase --continue' or 'hg rebase --abort') | (To continue: hg rebase --continue | ||||
| To abort: hg rebase --abort) | |||||
| [255] | [255] | ||||
| $ hg graft 3 | $ hg graft 3 | ||||
| abort: rebase in progress | abort: rebase in progress | ||||
| (use 'hg rebase --continue' or 'hg rebase --abort') | (To continue: hg rebase --continue | ||||
| To abort: hg rebase --abort) | |||||
| [255] | [255] | ||||
| $ hg rebase --abort | $ hg rebase --abort | ||||
| saved backup bundle to $TESTTMP/interrupted/.hg/strip-backup/3d8812cf300d-93041a90-backup.hg | saved backup bundle to $TESTTMP/interrupted/.hg/strip-backup/3d8812cf300d-93041a90-backup.hg | ||||
| rebase aborted | rebase aborted | ||||
| $ hg log -G --template "{rev} {desc} {bookmarks}" | $ hg log -G --template "{rev} {desc} {bookmarks}" | ||||
| o 6 no-a | o 6 no-a | ||||
| | | | | ||||
| unresolved conflicts (see hg resolve, then hg rebase --continue) | unresolved conflicts (see hg resolve, then hg rebase --continue) | ||||
| [1] | [1] | ||||
| $ hg rebase --stop --dry-run | $ hg rebase --stop --dry-run | ||||
| abort: cannot specify both --dry-run and --stop | abort: cannot specify both --dry-run and --stop | ||||
| [255] | [255] | ||||
| $ hg rebase -s 3 -d 5 | $ hg rebase -s 3 -d 5 | ||||
| abort: rebase in progress | abort: rebase in progress | ||||
| (use 'hg rebase --continue' or 'hg rebase --abort') | (To continue: hg rebase --continue | ||||
| To abort: hg rebase --abort) | |||||
| [255] | [255] | ||||
| $ hg rebase --stop --continue | $ hg rebase --stop --continue | ||||
| abort: cannot use --stop with --continue | abort: cannot use --stop with --continue | ||||
| [255] | [255] | ||||
| Test --stop moves bookmarks of original revisions to new rebased nodes: | Test --stop moves bookmarks of original revisions to new rebased nodes: | ||||
| ====================================================================== | ====================================================================== | ||||
| $ cd .. | $ cd .. | ||||
| $ hg histedit . -q --commands - << EOF | $ hg histedit . -q --commands - << EOF | ||||
| > edit d80cc2da061e histedit: generate unfinished state | > edit d80cc2da061e histedit: generate unfinished state | ||||
| > EOF | > EOF | ||||
| Editing (d80cc2da061e), you may commit or record as needed now. | Editing (d80cc2da061e), you may commit or record as needed now. | ||||
| (hg histedit --continue to resume) | (hg histedit --continue to resume) | ||||
| [1] | [1] | ||||
| $ hg pull --rebase | $ hg pull --rebase | ||||
| abort: histedit in progress | abort: histedit in progress | ||||
| (use 'hg histedit --continue' or 'hg histedit --abort') | (To continue: hg histedit --continue | ||||
| To abort: hg histedit --abort) | |||||
| [255] | [255] | ||||
| $ hg histedit --abort --quiet | $ hg histedit --abort --quiet | ||||
| Abort pull early with pending uncommitted merge: | Abort pull early with pending uncommitted merge: | ||||
| $ cd .. | $ cd .. | ||||
| $ hg clone --noupdate c d | $ hg clone --noupdate c d | ||||
| $ cd d | $ cd d | ||||
| rename to b.rename/b | rename to b.rename/b | ||||
| diff --git a/c b/c.copy | diff --git a/c b/c.copy | ||||
| copy from c | copy from c | ||||
| copy to c.copy | copy to c.copy | ||||
| $ hg resolve -l | $ hg resolve -l | ||||
| U a/a | U a/a | ||||
| $ hg shelve | $ hg shelve | ||||
| abort: unshelve already in progress | abort: unshelve in progress | ||||
| (use 'hg unshelve --continue' or 'hg unshelve --abort') | (To continue: hg unshelve --continue | ||||
| To abort: hg unshelve --abort) | |||||
| [255] | [255] | ||||
| abort the unshelve and be happy | abort the unshelve and be happy | ||||
| $ hg status | $ hg status | ||||
| M a/a | M a/a | ||||
| M b.rename/b | M b.rename/b | ||||
| M c.copy | M c.copy | ||||
| [255] | [255] | ||||
| $ hg revert -r . a/a | $ hg revert -r . a/a | ||||
| $ hg resolve -m a/a | $ hg resolve -m a/a | ||||
| (no more unresolved files) | (no more unresolved files) | ||||
| continue: hg unshelve --continue | continue: hg unshelve --continue | ||||
| $ hg commit -m 'commit while unshelve in progress' | $ hg commit -m 'commit while unshelve in progress' | ||||
| abort: unshelve already in progress | abort: unshelve in progress | ||||
| (use 'hg unshelve --continue' or 'hg unshelve --abort') | (To continue: hg unshelve --continue | ||||
| To abort: hg unshelve --abort) | |||||
| [255] | [255] | ||||
| $ hg graft --continue | $ hg graft --continue | ||||
| abort: no graft in progress | abort: no graft in progress | ||||
| (continue: hg unshelve --continue) | (continue: hg unshelve --continue) | ||||
| [255] | [255] | ||||
| $ hg unshelve -c | $ hg unshelve -c | ||||
| unshelve of 'default' complete | unshelve of 'default' complete | ||||
| patching file baz | patching file baz | ||||
| Hunk #1 FAILED at 0 | Hunk #1 FAILED at 0 | ||||
| 1 out of 1 hunks FAILED -- saving rejects to file baz.rej | 1 out of 1 hunks FAILED -- saving rejects to file baz.rej | ||||
| patch failed to apply | patch failed to apply | ||||
| abort: fix up the working directory and run hg transplant --continue | abort: fix up the working directory and run hg transplant --continue | ||||
| [255] | [255] | ||||
| $ hg transplant 1:3 | $ hg transplant 1:3 | ||||
| abort: transplant in progress | abort: transplant in progress | ||||
| (use 'hg transplant --continue' or 'hg update' to abort) | (To continue: hg transplant --continue | ||||
| To abort: hg update) | |||||
| [255] | [255] | ||||
| $ echo fixed > baz | $ echo fixed > baz | ||||
| $ hg transplant --continue | $ hg transplant --continue | ||||
| 9d6d6b5a8275 transplanted as d80c49962290 | 9d6d6b5a8275 transplanted as d80c49962290 | ||||
| applying 1dab759070cf | applying 1dab759070cf | ||||
| 1dab759070cf transplanted to aa0ffe6bd5ae | 1dab759070cf transplanted to aa0ffe6bd5ae | ||||
| $ cd .. | $ cd .. | ||||
Could your leave this change for a separate patch at the end (as I said before)? We try to separate refactoring from functional changes.