changeset 28205:53f42c8d5f71

verify: show progress while verifying dirlogs In repos with treemanifests, the non-root-directory dirlogs often have many more total revisions than the root manifest log has. This change adds progress out to that part of 'hg verify'. Since the verification is recursive along the directory tree, we don't know how many total revisions there are at the beginning of the command, so instead we report progress in units of directories, much like we report progress for verification of files today. I'm not very happy with passing both 'storefiles' and 'progress' into the recursive calls. I tried passing in just a 'visitdir(dir)' callback, but the results did not seem better overall. I'm happy to update if anyone has better ideas.
author Martin von Zweigbergk <martinvonz@google.com>
date Thu, 11 Feb 2016 15:38:56 -0800
parents 962921c330b0
children 8ab91d9290ce
files mercurial/verify.py
diffstat 1 files changed, 15 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/verify.py	Wed Feb 03 15:35:15 2016 -0800
+++ b/mercurial/verify.py	Thu Feb 11 15:38:56 2016 -0800
@@ -197,7 +197,8 @@
         ui.progress(_('checking'), None)
         return mflinkrevs, filelinkrevs
 
-    def _verifymanifest(self, mflinkrevs, dir="", storefiles=None):
+    def _verifymanifest(self, mflinkrevs, dir="", storefiles=None,
+                        progress=None):
         repo = self.repo
         ui = self.ui
         mf = self.repo.manifest.dirlog(dir)
@@ -213,6 +214,8 @@
             label = dir
             revlogfiles = mf.files()
             storefiles.difference_update(revlogfiles)
+            if progress: # should be true since we're in a subdirectory
+                progress()
         if self.refersmf:
             # Do not check manifest if there are only changelog entries with
             # null manifests.
@@ -263,19 +266,29 @@
         if not dir and subdirnodes:
             self.ui.status(_("checking directory manifests\n"))
             storefiles = set()
+            subdirs = 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))
+                    subdirs.add(os.path.dirname(f))
+            subdircount = len(subdirs)
+            currentsubdir = [0]
+            def progress():
+                currentsubdir[0] += 1
+                ui.progress(_('checking'), currentsubdir[0], total=subdircount,
+                            unit=_('manifests'))
 
         for subdir, linkrevs in subdirnodes.iteritems():
-            subdirfilenodes = self._verifymanifest(linkrevs, subdir, storefiles)
+            subdirfilenodes = self._verifymanifest(linkrevs, subdir, storefiles,
+                                                   progress)
             for f, onefilenodes in subdirfilenodes.iteritems():
                 filenodes.setdefault(f, {}).update(onefilenodes)
 
         if not dir and subdirnodes:
+            ui.progress(_('checking'), None)
             for f in sorted(storefiles):
                 self.warn(_("warning: orphan revlog '%s'") % f)