Patchwork [v2] shelve: make unshelve be able to abort in any case

login
register
mail settings
Submitter Kostia Balytskyi
Date July 7, 2016, 9:12 p.m.
Message ID <AM3PR06MB147B773603B7C94425190BCD33B0@AM3PR06MB147.eurprd06.prod.outlook.com>
Download mbox | patch
Permalink /patch/15772/
State Changes Requested
Headers show

Comments

Kostia Balytskyi - July 7, 2016, 9:12 p.m.
# HG changeset patch
# User Kostia Balytskyi <ikostia@fb.com>
# Date 1467925588 -7200
#      Thu Jul 07 23:06:28 2016 +0200
# Node ID f06ece8d99297bb9e3e8446be6bedff66acbb831
# Parent  b4d117cee636be8a566f56e84d4b351a736a1299
shelve: make unshelve be able to abort in any case
Anton Shestakov - July 8, 2016, 5:30 a.m.
08.07.2016, 05:12, "Kostia Balytskyi" <ikostia@fb.com>:
> # HG changeset patch
> # User Kostia Balytskyi <ikostia@fb.com>
> # Date 1467925588 -7200
> # Thu Jul 07 23:06:28 2016 +0200
> # Node ID f06ece8d99297bb9e3e8446be6bedff66acbb831
> # Parent b4d117cee636be8a566f56e84d4b351a736a1299
> shelve: make unshelve be able to abort in any case
>
> diff --git a/hgext/shelve.py b/hgext/shelve.py
> --- a/hgext/shelve.py
> +++ b/hgext/shelve.py
> @@ -662,10 +662,23 @@ def _dounshelve(ui, repo, *shelved, **op
>
>          try:
>              state = shelvedstate.load(repo)
> + except error.HintException:
> + raise
>          except IOError as err:
> - if err.errno != errno.ENOENT:
> - raise
> - cmdutil.wrongtooltocontinue(repo, _('unshelve'))
> + if err.errno == errno.ENOENT:
> + cmdutil.wrongtooltocontinue(repo, _('unshelve'))

Does this mean every other IOError now get silently ignored?

> + except Exception as err:
> + if continuef:
> + msg = _('could not read shelved state file\nplease run '
> + 'hg unshelve --abort to abort unshelve operation\n')
> + raise error.Abort(msg)

This could use hint for Abort exception, like:

msg = _('could not read shelved state file')
hint = _('run hg unshelve --abort to abort unshelve operation')
Abort(msg, hint=hint)

(Sorry for mangled white spaces.)
Yuya Nishihara - July 8, 2016, 1:32 p.m.
On Thu, 7 Jul 2016 21:12:41 +0000, Kostia Balytskyi wrote:
> # HG changeset patch
> # User Kostia Balytskyi <ikostia@fb.com>
> # Date 1467925588 -7200
> #      Thu Jul 07 23:06:28 2016 +0200
> # Node ID f06ece8d99297bb9e3e8446be6bedff66acbb831
> # Parent  b4d117cee636be8a566f56e84d4b351a736a1299
> shelve: make unshelve be able to abort in any case
> 
> diff --git a/hgext/shelve.py b/hgext/shelve.py
> --- a/hgext/shelve.py
> +++ b/hgext/shelve.py
> @@ -662,10 +662,23 @@ def _dounshelve(ui, repo, *shelved, **op
>  
>          try:
>              state = shelvedstate.load(repo)
> +        except error.HintException:
> +            raise

HintException isn't a category of error. I'll send a patch to make it private.

>          except IOError as err:
> -            if err.errno != errno.ENOENT:
> -                raise
> -            cmdutil.wrongtooltocontinue(repo, _('unshelve'))
> +            if err.errno == errno.ENOENT:
> +                cmdutil.wrongtooltocontinue(repo, _('unshelve'))

IOError would lost.

> +        except Exception as err:
> +            if continuef:
> +                msg = _('could not read shelved state file\nplease run '
> +                        'hg unshelve --abort to abort unshelve operation\n')
> +                raise error.Abort(msg)
> +            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

Catching "Exception" is too broad to detect corruption. Instead,
shelvedstate.load() can translate ValueError, TypeError, etc. to CorruptedState
or something.

Patch

diff --git a/hgext/shelve.py b/hgext/shelve.py
--- a/hgext/shelve.py
+++ b/hgext/shelve.py
@@ -662,10 +662,23 @@  def _dounshelve(ui, repo, *shelved, **op
 
         try:
             state = shelvedstate.load(repo)
+        except error.HintException:
+            raise
         except IOError as err:
-            if err.errno != errno.ENOENT:
-                raise
-            cmdutil.wrongtooltocontinue(repo, _('unshelve'))
+            if err.errno == errno.ENOENT:
+                cmdutil.wrongtooltocontinue(repo, _('unshelve'))
+        except Exception as err:
+            if continuef:
+                msg = _('could not read shelved state file\nplease run '
+                        'hg unshelve --abort to abort unshelve operation\n')
+                raise error.Abort(msg)
+            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
 
         if abortf:
             return unshelveabort(ui, repo, state, opts)
diff --git a/tests/test-shelve.t b/tests/test-shelve.t
--- a/tests/test-shelve.t
+++ b/tests/test-shelve.t
@@ -1585,3 +1585,41 @@  On non bare shelve the branch informatio
   ? b
   $ hg branch
   default
+  $ cd ..
+
+Prepare unshleve 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
+  rebasing 1:396ea74229f9 "(changes in empty repository)" (tip)
+  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 --continue fails with appropriate message if shelvedstate is corrupted
+  $ hg unshelve --continue
+  abort: could not read shelved state file
+  please run hg unshelve --abort to abort unshelve operation
+  
+  [255]
+
+Unshelve --abort works with a corrupted shelvedstate
+  $ hg unshelve --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 unshelve --abort
+  abort: no unshelve in progress
+  [255]
+  $ cd ..