shelve: don't include invalid shelves in `hg shelve --list`
authorMartin von Zweigbergk <martinvonz@google.com>
Mon, 11 Jan 2021 09:26:48 -0800
changeset 46288 61f8fc12e167
parent 46287 ae7a77a7ebc0
child 46289 c062874a35db
shelve: don't include invalid shelves in `hg shelve --list` Before this patch, if a shelved change is missing its `.hg` file, we still list it in `hg shelve --list`, but then `hg unshelve` crashes. This patch makes it so we only list valid shelved changes. This patch means that users who do `touch .hg/shelve/buy-milk.patch` as a form of TODO list will no longer see their TODO items in `hg shelve --list`. Differential Revision: https://phab.mercurial-scm.org/D9719
mercurial/shelve.py
tests/test-shelve2.t
--- a/mercurial/shelve.py	Thu Jan 07 23:32:19 2021 -0800
+++ b/mercurial/shelve.py	Mon Jan 11 09:26:48 2021 -0800
@@ -87,7 +87,9 @@
         self.backupvfs = vfsmod.vfs(repo.vfs.join(backupdir))
 
     def exists(self):
-        return self.vfs.exists(self.name + b'.' + patchextension)
+        return self.vfs.exists(
+            self.name + b'.' + patchextension
+        ) and self.vfs.exists(self.name + b'.hg')
 
     def mtime(self):
         return self.vfs.stat(self.name + b'.' + patchextension)[stat.ST_MTIME]
@@ -621,12 +623,17 @@
             raise
         return []
     info = []
-    for (name, _type) in names:
-        pfx, sfx = name.rsplit(b'.', 1)
-        if not pfx or sfx != patchextension:
+    seen = set()
+    for (filename, _type) in names:
+        name, ext = filename.rsplit(b'.', 1)
+        if name in seen:
             continue
-        mtime = Shelf(repo, pfx).mtime()
-        info.append((mtime, pfx))
+        seen.add(name)
+        shelf = Shelf(repo, name)
+        if not shelf.exists():
+            continue
+        mtime = shelf.mtime()
+        info.append((mtime, name))
     return sorted(info, reverse=True)
 
 
--- a/tests/test-shelve2.t	Thu Jan 07 23:32:19 2021 -0800
+++ b/tests/test-shelve2.t	Mon Jan 11 09:26:48 2021 -0800
@@ -753,16 +753,15 @@
 # A (corrupt) .patch file without a .hg file
   $ touch .hg/shelved/junk1.patch
   $ hg shelve -l
-  junk1           (* ago)     (glob)
   $ hg unshelve
-  unshelving change 'junk1'
-  abort: $ENOENT$: '$TESTTMP/corrupt-shelves/.hg/shelved/junk1.hg'
-  [255]
+  abort: no shelved changes to apply!
+  [20]
   $ hg shelve -d junk1
+  abort: shelved change 'junk1' not found
+  [10]
   $ find .hg/shelve* | sort
-  .hg/shelve-backup
-  .hg/shelve-backup/junk1.patch
   .hg/shelved
+  .hg/shelved/junk1.patch
 
 # A .hg file without a .patch file
   $ touch .hg/shelved/junk2.hg
@@ -774,9 +773,8 @@
   abort: shelved change 'junk2' not found
   [10]
   $ find .hg/shelve* | sort
-  .hg/shelve-backup
-  .hg/shelve-backup/junk1.patch
   .hg/shelved
+  .hg/shelved/junk1.patch
   .hg/shelved/junk2.hg
 
 # A file with an unexpected extension
@@ -789,9 +787,8 @@
   abort: shelved change 'junk3' not found
   [10]
   $ find .hg/shelve* | sort
-  .hg/shelve-backup
-  .hg/shelve-backup/junk1.patch
   .hg/shelved
+  .hg/shelved/junk1.patch
   .hg/shelved/junk2.hg
   .hg/shelved/junk3