# HG changeset patch # User Taapas Agrawal # Date 2019-06-26 16:45:07 # Node ID 3fb0493812c02955e9f0dcb78266dd82f4210053 # Parent 8ddfdcce4bd603efe4f8f5620773bbee1f3b1bb5 abort: added support for unshelve This patch adds the support for shelve in `hg abort` plan. For this the logic to load a `shelvedstate` and the error handling for it had been shifted to a seperate function `_loadunshelvedstate()`. This returns a tuple with `state` file and `opts.` `hgabortunshelve()` has been created for independent calls. In case abortion of `unshelve` is called via `hg abort` the `shelvedstate` needs to be loaded seperately. This has been ensured by `_loadunshelvedstate()` `hgabortunshelve()` is then registered as `abortfunc` for state detection API. Results are shown as tests. Differential Revision: https://phab.mercurial-scm.org/D6579 diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -6182,6 +6182,12 @@ def unshelve(ui, repo, *shelved, **opts) with repo.wlock(): return shelvemod.dounshelve(ui, repo, *shelved, **opts) +statemod.addunfinished( + 'unshelve', fname='shelvedstate', continueflag=True, + abortfunc=shelvemod.hgabortunshelve, + cmdmsg=_('unshelve already in progress'), +) + @command('update|up|checkout|co', [('C', 'clean', None, _('discard uncommitted changes (no backup)')), ('c', 'check', None, _('require clean working directory')), diff --git a/mercurial/shelve.py b/mercurial/shelve.py --- a/mercurial/shelve.py +++ b/mercurial/shelve.py @@ -624,7 +624,30 @@ def checkparents(repo, state): raise error.Abort(_('working directory parents do not match unshelve ' 'state')) -def unshelveabort(ui, repo, state, opts): +def _loadshelvedstate(ui, repo, opts): + try: + state = shelvedstate.load(repo) + if opts.get('keep') is None: + opts['keep'] = state.keep + except IOError as err: + if err.errno != errno.ENOENT: + raise + cmdutil.wrongtooltocontinue(repo, _('unshelve')) + except error.CorruptedState as err: + ui.debug(pycompat.bytestr(err) + '\n') + if opts.get('continue'): + msg = _('corrupted shelved state file') + hint = _('please run hg unshelve --abort to abort unshelve ' + 'operation') + raise error.Abort(msg, hint=hint) + elif opts.get('abort'): + shelvedstate.clear(repo) + raise error.Abort(_('could not read shelved state file, your ' + 'working copy may be in an unexpected state\n' + 'please update to some commit\n')) + return state + +def unshelveabort(ui, repo, state): """subcommand that abort an in-progress unshelve""" with repo.lock(): try: @@ -642,6 +665,12 @@ def unshelveabort(ui, repo, state, opts) shelvedstate.clear(repo) ui.warn(_("unshelve of '%s' aborted\n") % state.name) +def hgabortunshelve(ui, repo): + """logic to abort unshelve using 'hg abort""" + with repo.wlock(): + state = _loadshelvedstate(ui, repo, {'abort' : True}) + return unshelveabort(ui, repo, state) + def mergefiles(ui, repo, wctx, shelvectx): """updates to wctx and merges the changes from shelvectx into the dirstate.""" @@ -665,7 +694,6 @@ def unshelvecleanup(ui, repo, name, opts if shfile.exists(): shfile.movetobackup() cleanupoldbackups(repo) - def unshelvecontinue(ui, repo, state, opts): """subcommand to continue an in-progress unshelve""" # We're finishing off a merge. First parent is our original @@ -864,29 +892,9 @@ def dounshelve(ui, repo, *shelved, **opt if abortf and opts.get('tool', False): ui.warn(_('tool option will be ignored\n')) - try: - state = shelvedstate.load(repo) - if opts.get('keep') is None: - opts['keep'] = state.keep - except IOError as err: - if err.errno != errno.ENOENT: - raise - cmdutil.wrongtooltocontinue(repo, _('unshelve')) - except error.CorruptedState as err: - ui.debug(pycompat.bytestr(err) + '\n') - if continuef: - msg = _('corrupted shelved state file') - hint = _('please run hg unshelve --abort to abort unshelve ' - 'operation') - raise error.Abort(msg, hint=hint) - elif abortf: - shelvedstate.clear(repo) - raise error.Abort(_('could not read shelved state file, your ' - 'working copy may be in an unexpected state\n' - 'please update to some commit\n')) - + state = _loadshelvedstate(ui, repo, opts) if abortf: - return unshelveabort(ui, repo, state, opts) + return unshelveabort(ui, repo, state) elif continuef: return unshelvecontinue(ui, repo, state, opts) elif len(shelved) > 1: diff --git a/mercurial/state.py b/mercurial/state.py --- a/mercurial/state.py +++ b/mercurial/state.py @@ -194,10 +194,6 @@ def addunfinished(opname, fname, clearab _unfinishedstates.insert(0, statecheckobj) addunfinished( - 'unshelve', fname='shelvedstate', continueflag=True, - cmdmsg=_('unshelve already in progress') -) -addunfinished( 'update', fname='updatestate', clearable=True, cmdmsg=_('last update was interrupted'), cmdhint=_("use 'hg update' to get a consistent checkout"), diff --git a/tests/test-shelve2.t b/tests/test-shelve2.t --- a/tests/test-shelve2.t +++ b/tests/test-shelve2.t @@ -1,4 +1,5 @@ #testcases stripbased phasebased +#testcases abortflag abortcommand $ cat <> $HGRCPATH > [extensions] @@ -19,6 +20,13 @@ #endif +#if abortflag + $ cat >> $HGRCPATH < [alias] + > abort = unshelve --abort + > EOF +#endif + shelve should leave dirstate clean (issue4055) $ hg init shelverebase @@ -285,7 +293,14 @@ unshelve and conflicts with tracked and >>>>>>> working-copy: aef214a5229c - shelve: changes to: commit stuff $ cat f.orig g - $ hg unshelve --abort + +#if abortcommand +when in dry-run mode + $ hg abort --dry-run + unshelve in progress, will be aborted +#endif + + $ hg abort unshelve of 'default' aborted $ hg st ? f.orig @@ -695,7 +710,7 @@ Unshelve --continue fails with appropria [255] Unshelve --abort works with a corrupted shelvedstate - $ hg unshelve --abort + $ hg abort abort: could not read shelved state file, your working copy may be in an unexpected state please update to some commit @@ -703,8 +718,10 @@ Unshelve --abort works with a corrupted Unshelve --abort fails with appropriate message if there's no unshelve in progress - $ hg unshelve --abort - abort: no unshelve in progress + $ hg abort + abort: no unshelve in progress (abortflag !) + abort: merge in progress but does not support 'hg abort' (no-abortflag !) + (use 'hg commit' or 'hg merge --abort') (no-abortflag !) [255] $ cd .. @@ -824,7 +841,7 @@ Test with the `.shelve` missing, but the warning: conflicts while merging a! (edit, then use 'hg resolve --mark') unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue') [1] - $ hg unshelve --abort + $ hg abort unshelve of 'default' aborted Unshelve without .shelve metadata (can happen when upgrading a repository with old shelve) @@ -843,7 +860,7 @@ Unshelve without .shelve metadata (can h [1] $ cat .hg/shelved/default.shelve node=82e0cb9893247d12667017593ce1e5655860f1ac - $ hg unshelve --abort + $ hg abort unshelve of 'default' aborted #endif