Patchwork shelve: fix crash on unshelve without .shelve metadata file

login
register
mail settings
Submitter Yuya Nishihara
Date Aug. 31, 2018, 12:30 p.m.
Message ID <1eae14fe0f9b3ed85929.1535718604@mimosa>
Download mbox | patch
Permalink /patch/34204/
State Accepted
Headers show

Comments

Yuya Nishihara - Aug. 31, 2018, 12:30 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1535717428 -32400
#      Fri Aug 31 21:10:28 2018 +0900
# Node ID 1eae14fe0f9b3ed85929b6ce806c6d5a6a355117
# Parent  b64d36e5ca31cc25e159f0fc3e710dbf46b89546
shelve: fix crash on unshelve without .shelve metadata file

Follow up for c67c94c0e7ae and 38373da1af02.

The inline comment says "we should keep track of the unshelve node in case
we need to reuse it." Perhaps such case isn't tested, and this patch does
NOT add a test for the reuse of the unbundled revision.

Also, I have no idea what should be done if new revision is unbundled
because of "node not in repo".
Augie Fackler - Sept. 1, 2018, 2:38 p.m.
queued 

> On Aug 31, 2018, at 8:30 AM, Yuya Nishihara <yuya@tcha.org> wrote:
> 
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1535717428 -32400
> #      Fri Aug 31 21:10:28 2018 +0900
> # Node ID 1eae14fe0f9b3ed85929b6ce806c6d5a6a355117
> # Parent  b64d36e5ca31cc25e159f0fc3e710dbf46b89546
> shelve: fix crash on unshelve without .shelve metadata file
> 
> Follow up for c67c94c0e7ae and 38373da1af02.
> 
> The inline comment says "we should keep track of the unshelve node in case
> we need to reuse it." Perhaps such case isn't tested, and this patch does
> NOT add a test for the reuse of the unbundled revision.
> 
> Also, I have no idea what should be done if new revision is unbundled
> because of "node not in repo".
> 
> diff --git a/hgext/shelve.py b/hgext/shelve.py
> --- a/hgext/shelve.py
> +++ b/hgext/shelve.py
> @@ -765,6 +765,7 @@ def _commitworkingcopychanges(ui, repo, 
> def _unshelverestorecommit(ui, repo, basename):
>     """Recreate commit in the repository during the unshelve"""
>     repo = repo.unfiltered()
> +    node = None
>     if shelvedfile(repo, basename, 'shelve').exists():
>         node = shelvedfile(repo, basename, 'shelve').readinfo()['node']
>     if node is None or node not in repo:
> @@ -774,7 +775,7 @@ def _unshelverestorecommit(ui, repo, bas
>         # We might not strip the unbundled changeset, so we should keep track of
>         # the unshelve node in case we need to reuse it (eg: unshelve --keep)
>         if node is None:
> -            info = {'node': nodemod.hex(node)}
> +            info = {'node': nodemod.hex(shelvectx.node())}
>             shelvedfile(repo, basename, 'shelve').writeinfo(info)
>     else:
>         shelvectx = repo[node]
> diff --git a/tests/test-shelve.t b/tests/test-shelve.t
> --- a/tests/test-shelve.t
> +++ b/tests/test-shelve.t
> @@ -1793,5 +1793,23 @@ putting v1 shelvedstate file in place of
> mercurial does not crash
>   $ hg unshelve --continue
>   unshelve of 'ashelve' complete
> +
> +Unshelve without .shelve metadata:
> +
> +  $ hg shelve
> +  shelved as default
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ rm .hg/shelved/default.shelve
> +  $ echo 3 > a
> +  $ hg unshelve
> +  unshelving change 'default'
> +  temporarily committing pending changes (restore with 'hg unshelve --abort')
> +  rebasing shelved changes
> +  merging a
> +  warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
> +  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
> +  [1]
> +  $ cat .hg/shelved/default.shelve
> +  node=82e0cb9893247d12667017593ce1e5655860f1ac
> +
>   $ cd ..
> -
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff --git a/hgext/shelve.py b/hgext/shelve.py
--- a/hgext/shelve.py
+++ b/hgext/shelve.py
@@ -765,6 +765,7 @@  def _commitworkingcopychanges(ui, repo, 
 def _unshelverestorecommit(ui, repo, basename):
     """Recreate commit in the repository during the unshelve"""
     repo = repo.unfiltered()
+    node = None
     if shelvedfile(repo, basename, 'shelve').exists():
         node = shelvedfile(repo, basename, 'shelve').readinfo()['node']
     if node is None or node not in repo:
@@ -774,7 +775,7 @@  def _unshelverestorecommit(ui, repo, bas
         # We might not strip the unbundled changeset, so we should keep track of
         # the unshelve node in case we need to reuse it (eg: unshelve --keep)
         if node is None:
-            info = {'node': nodemod.hex(node)}
+            info = {'node': nodemod.hex(shelvectx.node())}
             shelvedfile(repo, basename, 'shelve').writeinfo(info)
     else:
         shelvectx = repo[node]
diff --git a/tests/test-shelve.t b/tests/test-shelve.t
--- a/tests/test-shelve.t
+++ b/tests/test-shelve.t
@@ -1793,5 +1793,23 @@  putting v1 shelvedstate file in place of
 mercurial does not crash
   $ hg unshelve --continue
   unshelve of 'ashelve' complete
+
+Unshelve without .shelve metadata:
+
+  $ hg shelve
+  shelved as default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ rm .hg/shelved/default.shelve
+  $ echo 3 > a
+  $ hg unshelve
+  unshelving change 'default'
+  temporarily committing pending changes (restore with 'hg unshelve --abort')
+  rebasing shelved changes
+  merging a
+  warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
+  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
+  [1]
+  $ cat .hg/shelved/default.shelve
+  node=82e0cb9893247d12667017593ce1e5655860f1ac
+
   $ cd ..
-