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