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

Kostia Balytskyi ikostia at fb.com
Thu Jan 19 17:51:24 UTC 2017


# HG changeset patch
# User Kostia Balytskyi <ikostia at 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.

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


More information about the Mercurial-devel mailing list