Patchwork [shelve-ext] shelve: make unshelve not crash when there are missing files (issue4176)

login
register
mail settings
Submitter Kostia Balytskyi
Date Jan. 19, 2017, 5:51 p.m.
Message ID <2a1e998e369d2c5dc828.1484848284@devvm1416.lla2.facebook.com>
Download mbox | patch
Permalink /patch/18261/
State Accepted
Headers show

Comments

Kostia Balytskyi - Jan. 19, 2017, 5:51 p.m.
# HG changeset patch
# User Kostia Balytskyi <ikostia@fb.com>
# Date 1484848120 28800
#      Thu Jan 19 09:48:40 2017 -0800
# Node ID 2a1e998e369d2c5dc828ba805beceb15459746cd
# Parent  9f264adbe75bfae8551dc0e6e0fce8d43fc7b43a
shelve: make unshelve not crash when there are missing files (issue4176)

This patch makes it possible to unshelve while having missing files
in your repo as long as shelved changes don't touch those missing files.
It also makes error message better otherwise.
Sean Farley - Jan. 19, 2017, 7:34 p.m.
Kostia Balytskyi <ikostia@fb.com> writes:

> # HG changeset patch
> # User Kostia Balytskyi <ikostia@fb.com>
> # Date 1484848120 28800
> #      Thu Jan 19 09:48:40 2017 -0800
> # Node ID 2a1e998e369d2c5dc828ba805beceb15459746cd
> # Parent  9f264adbe75bfae8551dc0e6e0fce8d43fc7b43a
> shelve: make unshelve not crash when there are missing files (issue4176)
>
> This patch makes it possible to unshelve while having missing files
> in your repo as long as shelved changes don't touch those missing files.
> It also makes error message better otherwise.

This patch seems good to me from an initial reading and probably belongs
on stable.
Augie Fackler - Jan. 19, 2017, 9:54 p.m.
On Thu, Jan 19, 2017 at 09:51:24AM -0800, Kostia Balytskyi wrote:
> # HG changeset patch
> # User Kostia Balytskyi <ikostia@fb.com>
> # Date 1484848120 28800
> #      Thu Jan 19 09:48:40 2017 -0800
> # Node ID 2a1e998e369d2c5dc828ba805beceb15459746cd
> # Parent  9f264adbe75bfae8551dc0e6e0fce8d43fc7b43a
> shelve: make unshelve not crash when there are missing files (issue4176)

Queued for stable, thanks.

>
> This patch makes it possible to unshelve while having missing files
> in your repo as long as shelved changes don't touch those missing files.
> It also makes error message better otherwise.
>
> diff --git a/hgext/shelve.py b/hgext/shelve.py
> --- a/hgext/shelve.py
> +++ b/hgext/shelve.py
> @@ -650,7 +650,7 @@ def _commitworkingcopychanges(ui, repo,
>      # contains unknown files that are part of the pending change
>      s = repo.status()
>      addedbefore = frozenset(s.added)
> -    if not (s.modified or s.added or s.removed or s.deleted):
> +    if not (s.modified or s.added or s.removed):
>          return tmpwctx, addedbefore
>      ui.status(_("temporarily committing pending changes "
>                  "(restore with 'hg unshelve --abort')\n"))
> @@ -729,6 +729,17 @@ def _finishunshelve(repo, oldtiprev, tr)
>      repo.unfiltered().changelog.strip(oldtiprev, tr)
>      _aborttransaction(repo)
>
> +def _checkunshelveuntrackedproblems(ui, repo, shelvectx):
> +    """Check potential problems which may result from working
> +    copy having untracked changes."""
> +    wcdeleted = set(repo.status().deleted)
> +    shelvetouched = set(shelvectx.files())
> +    intersection = wcdeleted.intersection(shelvetouched)
> +    if intersection:
> +        m = _("shelved change touches missing files")
> +        hint = _("run hg status to see which files are missing")
> +        raise error.Abort(m, hint=hint)
> +
>  @command('unshelve',
>           [('a', 'abort', None,
>             _('abort an incomplete unshelve operation')),
> @@ -857,7 +868,7 @@ def _dounshelve(ui, repo, *shelved, **op
>                                                           tmpwctx)
>
>          repo, shelvectx = _unshelverestorecommit(ui, repo, basename, oldquiet)
> -
> +        _checkunshelveuntrackedproblems(ui, repo, shelvectx)
>          branchtorestore = ''
>          if shelvectx.branch() != shelvectx.p1().branch():
>              branchtorestore = shelvectx.branch()
> diff --git a/tests/test-shelve.t b/tests/test-shelve.t
> --- a/tests/test-shelve.t
> +++ b/tests/test-shelve.t
> @@ -1710,3 +1710,30 @@ Unshelve respects --keep even if user in
>    $ hg shelve --list
>    default         (*s ago)    changes to: 1 (glob)
>    $ cd ..
> +
> +Unshelving when there are deleted files does not crash (issue4176)
> +  $ hg init unshelve-deleted-file && cd unshelve-deleted-file
> +  $ echo a > a && echo b > b && hg ci -Am ab
> +  adding a
> +  adding b
> +  $ echo aa > a && hg shelve
> +  shelved as default
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ rm b
> +  $ hg st
> +  ! b
> +  $ hg unshelve
> +  unshelving change 'default'
> +  $ hg shelve
> +  shelved as default
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  $ rm a && echo b > b
> +  $ hg st
> +  ! a
> +  $ hg unshelve
> +  unshelving change 'default'
> +  abort: shelved change touches missing files
> +  (run hg status to see which files are missing)
> +  [255]
> +  $ hg st
> +  ! a
> _______________________________________________
> 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
@@ -650,7 +650,7 @@  def _commitworkingcopychanges(ui, repo, 
     # contains unknown files that are part of the pending change
     s = repo.status()
     addedbefore = frozenset(s.added)
-    if not (s.modified or s.added or s.removed or s.deleted):
+    if not (s.modified or s.added or s.removed):
         return tmpwctx, addedbefore
     ui.status(_("temporarily committing pending changes "
                 "(restore with 'hg unshelve --abort')\n"))
@@ -729,6 +729,17 @@  def _finishunshelve(repo, oldtiprev, tr)
     repo.unfiltered().changelog.strip(oldtiprev, tr)
     _aborttransaction(repo)
 
+def _checkunshelveuntrackedproblems(ui, repo, shelvectx):
+    """Check potential problems which may result from working
+    copy having untracked changes."""
+    wcdeleted = set(repo.status().deleted)
+    shelvetouched = set(shelvectx.files())
+    intersection = wcdeleted.intersection(shelvetouched)
+    if intersection:
+        m = _("shelved change touches missing files")
+        hint = _("run hg status to see which files are missing")
+        raise error.Abort(m, hint=hint)
+
 @command('unshelve',
          [('a', 'abort', None,
            _('abort an incomplete unshelve operation')),
@@ -857,7 +868,7 @@  def _dounshelve(ui, repo, *shelved, **op
                                                          tmpwctx)
 
         repo, shelvectx = _unshelverestorecommit(ui, repo, basename, oldquiet)
-
+        _checkunshelveuntrackedproblems(ui, repo, shelvectx)
         branchtorestore = ''
         if shelvectx.branch() != shelvectx.p1().branch():
             branchtorestore = shelvectx.branch()
diff --git a/tests/test-shelve.t b/tests/test-shelve.t
--- a/tests/test-shelve.t
+++ b/tests/test-shelve.t
@@ -1710,3 +1710,30 @@  Unshelve respects --keep even if user in
   $ hg shelve --list
   default         (*s ago)    changes to: 1 (glob)
   $ cd ..
+
+Unshelving when there are deleted files does not crash (issue4176)
+  $ hg init unshelve-deleted-file && cd unshelve-deleted-file
+  $ echo a > a && echo b > b && hg ci -Am ab
+  adding a
+  adding b
+  $ echo aa > a && hg shelve
+  shelved as default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ rm b
+  $ hg st
+  ! b
+  $ hg unshelve
+  unshelving change 'default'
+  $ hg shelve
+  shelved as default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ rm a && echo b > b
+  $ hg st
+  ! a
+  $ hg unshelve
+  unshelving change 'default'
+  abort: shelved change touches missing files
+  (run hg status to see which files are missing)
+  [255]
+  $ hg st
+  ! a