diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -6262,6 +6262,11 @@ with repo.wlock(): return shelvemod._dounshelve(ui, repo, *shelved, **opts) +statemod.addunfinished( + 'unshelve', fname='shelvedstate', continueflag=True, + cmdmsg=_('unshelve already in progress'), abortfunc=shelvemod.unshelveabort +) + @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,9 +624,25 @@ raise error.Abort(_('working directory parents do not match unshelve ' 'state')) -def unshelveabort(ui, repo, state, opts): +def unshelveabort(ui, repo, state=None): """subcommand that abort an in-progress unshelve""" - with repo.lock(): + if not state: + try: + state = shelvedstate.load(repo) + 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') + msg = _('could not read shelved state file, your working copy ' + 'may be in an unexpected state\nplease update to some ' + 'commit\n') + ui.warn(msg) + shelvedstate.clear(repo) + return + + with repo.wlock(), repo.lock(): try: checkparents(repo, state) @@ -888,7 +904,7 @@ return 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 @@ _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-abort.t b/tests/test-abort.t --- a/tests/test-abort.t +++ b/tests/test-abort.t @@ -1,9 +1,8 @@ -####TEST `hg abort` operation rebase - $ cat >> $HGRCPATH < [extensions] > rebase= - > + > shelve= + > mq = > [phases] > publish=False > @@ -11,7 +10,7 @@ > tglog = log -G --template "{rev}:{phase} '{desc}' {branches}\n" > EOF - +####TEST `hg abort` operation rebase $ hg init a $ cd a @@ -630,3 +629,95 @@ cannot clean up public changesets 6ec71c037d94 graft aborted working directory is now at 6ec71c037d94 + $ cd .. + +###TEST `hg abort` operation unshelve + +Prepare unshelve with a corrupted shelvedstate + $ hg init r1 && cd r1 + $ echo text1 > file && hg add file + $ hg shelve + shelved as default + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo text2 > file && hg ci -Am text1 + adding file + $ hg unshelve + unshelving change 'default' + rebasing shelved changes + merging file + warning: conflicts while merging file! (edit, then use 'hg resolve --mark') + unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue') + [1] + $ echo somethingsomething > .hg/shelvedstate + +Unshelve abort works with a corrupted shelvedstate + $ hg abort + could not read shelved state file, your working copy may be in an unexpected state + please update to some commit + +Unshelve abort fails with appropriate message if there's no unshelve in +progress + $ hg abort + abort: merge does not support 'hg abort' + (use 'hg commit' or 'hg merge --abort') + [255] + $ cd .. + +Abort due to pending changes + $ hg init onlypendingchanges + $ cd onlypendingchanges + $ touch a + $ hg ci -Aqm a + $ echo f > f + $ hg add f + $ hg shelve + shelved as default + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo g > f + $ echo 1 > a + $ hg unshelve + unshelving change 'default' + temporarily committing pending changes (restore with 'hg unshelve --abort') + rebasing shelved changes + merging f + warning: conflicts while merging f! (edit, then use 'hg resolve --mark') + unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue') + [1] + $ hg st + M f + ? f.orig + $ cat f + <<<<<<< shelve: f0be9a229575 - shelve: pending changes temporary commit + g + ======= + f + >>>>>>> working-copy: 7d4133053e12 - shelve: changes to: a + $ cat f.orig + g + $ hg ci a -m 'intermediate other change' + abort: unshelve already in progress + (use 'hg unshelve --continue' or 'hg unshelve --abort') + [255] + +when in dry-run mode + $ hg abort --dry-run + abort: aborting unshelve + [255] + +when in no-backup mode + $ hg abort --no-backup + abort: unshelve does not support no-backup + [255] + +when dry-run mode is used with no backup + $ hg abort --dry-run --no-backup + abort: unshelve does not support no-backup + [255] + +normal abort + $ hg abort + unshelve of 'default' aborted + $ cd .. + + +