D6579: abort: added support for unshelve

taapas1128 (Taapas Agrawal) phabricator at mercurial-scm.org
Thu Jul 4 11:00:58 EDT 2019


taapas1128 updated this revision to Diff 15756.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6579?vs=15753&id=15756

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6579/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6579

AFFECTED FILES
  mercurial/commands.py
  mercurial/shelve.py
  mercurial/state.py
  tests/test-abort.t

CHANGE DETAILS

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 <<EOF
   > [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
+  aborting unshelve
+
+when in no-backup mode
+  $ hg abort --no-backup
+  abort: unshelve does not support no-backup flag
+  [255]
+
+when dry-run mode is used with no backup
+  $ hg abort --dry-run --no-backup
+  aborting unshelve
+  abort: unshelve does not support no-backup flag
+  [255]
+
+normal abort
+  $ hg abort
+  unshelve of 'default' aborted
+  $ cd ..
+
+
+
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/mercurial/shelve.py b/mercurial/shelve.py
--- a/mercurial/shelve.py
+++ b/mercurial/shelve.py
@@ -26,6 +26,7 @@
 import errno
 import itertools
 import stat
+import sys
 
 from .i18n import _
 from . import (
@@ -624,9 +625,41 @@
         raise error.Abort(_('working directory parents do not match unshelve '
                            'state'))
 
-def unshelveabort(ui, repo, state, opts):
+def _loadshelvedstate(ui, repo, continuef=False, abortf=False, **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 continuef:
+            msg = _('corrupted shelved state file')
+            hint = _('please run hg unshelve --abort to abort unshelve '
+                     'operation')
+            raise error.Abort(msg, hint=hint)
+        elif abortf:
+            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)
+        sys.exit()
+    return (state, opts)
+
+def unshelveabort(ui, repo, state=None, **opts):
     """subcommand that abort an in-progress unshelve"""
-    with repo.lock():
+    if opts.get('no_backup'):
+        raise error.Abort(_("unshelve does not support no-backup flag"))
+    if opts.get('dry_run'):
+        return 0
+    if not state:
+        statetuple = _loadshelvedstate(ui, repo, abortf=True, **opts)
+        state, opts = statetuple
+    with repo.wlock(), repo.lock():
         try:
             checkparents(repo, state)
 
@@ -864,31 +897,12 @@
         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:
-                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
+        statetuple = _loadshelvedstate(ui, repo, continuef=continuef,
+                                       abortf=abortf, **opts)
+        state, opts = statetuple
 
         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/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -6259,6 +6259,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')),



To: taapas1128, #hg-reviewers
Cc: pulkit, mercurial-devel


More information about the Mercurial-devel mailing list