diff mercurial/verify.py @ 28204:962921c330b0

verify: check for orphaned dirlogs We already report orphaned filelogs, i.e. revlogs for files that are not mentioned in any manifest. This change adds checking for orphaned dirlogs, i.e. revlogs that are not mentioned in any parent-directory dirlog. Note that, for fncachestore, only files mentioned in the fncache are considered, there's not check for files in .hg/store/meta that are not mentioned in the fncache. This is no different from the current situation for filelogs.
author Martin von Zweigbergk <martinvonz@google.com>
date Wed, 03 Feb 2016 15:35:15 -0800
parents 7297e9e13a8a
children 53f42c8d5f71
line wrap: on
line diff
--- a/mercurial/verify.py	Sun Feb 07 21:13:24 2016 -0800
+++ b/mercurial/verify.py	Wed Feb 03 15:35:15 2016 -0800
@@ -197,7 +197,7 @@
         ui.progress(_('checking'), None)
         return mflinkrevs, filelinkrevs
 
-    def _verifymanifest(self, mflinkrevs, dir=""):
+    def _verifymanifest(self, mflinkrevs, dir="", storefiles=None):
         repo = self.repo
         ui = self.ui
         mf = self.repo.manifest.dirlog(dir)
@@ -211,6 +211,8 @@
         label = "manifest"
         if dir:
             label = dir
+            revlogfiles = mf.files()
+            storefiles.difference_update(revlogfiles)
         if self.refersmf:
             # Do not check manifest if there are only changelog entries with
             # null manifests.
@@ -260,11 +262,23 @@
 
         if not dir and subdirnodes:
             self.ui.status(_("checking directory manifests\n"))
+            storefiles = set()
+            revlogv1 = self.revlogv1
+            for f, f2, size in repo.store.datafiles():
+                if not f:
+                    self.err(None, _("cannot decode filename '%s'") % f2)
+                elif (size > 0 or not revlogv1) and f.startswith('meta/'):
+                    storefiles.add(_normpath(f))
+
         for subdir, linkrevs in subdirnodes.iteritems():
-            subdirfilenodes = self._verifymanifest(linkrevs, subdir)
+            subdirfilenodes = self._verifymanifest(linkrevs, subdir, storefiles)
             for f, onefilenodes in subdirfilenodes.iteritems():
                 filenodes.setdefault(f, {}).update(onefilenodes)
 
+        if not dir and subdirnodes:
+            for f in sorted(storefiles):
+                self.warn(_("warning: orphan revlog '%s'") % f)
+
         return filenodes
 
     def _crosscheckfiles(self, filelinkrevs, filenodes):
@@ -402,7 +416,7 @@
                              short(node), f)
         ui.progress(_('checking'), None)
 
-        for f in storefiles:
+        for f in sorted(storefiles):
             self.warn(_("warning: orphan revlog '%s'") % f)
 
         return len(files), revisions