verify: add a config option to skip certain flag processors
authorJun Wu <quark@fb.com>
Sun, 14 May 2017 09:38:06 -0700
changeset 37443 a2ab9ebcd85b09e33d3036ceccb2dff6f6353e79
parent 37442 df3cf9422e1bb0287f281fd169fb0a8673bd547b
child 37455 770bbfdc9644b7261bf2c2c28300f19c2c61176e
push id512
push usergszorc@mozilla.com
push dateTue, 16 May 2017 02:40:46 +0000
verify: add a config option to skip certain flag processors Previously, "hg verify" verifies everything, which could be undesirable when there are expensive flag processor contents. This patch adds a "verify.skipflags" developer config. A flag processor will be skipped if (flag & verify.skipflags) == 0. In the LFS usecase, that means "hg verify --config verify.skipflags=8192" will not download all LFS blobs, which could be too large to be stored locally. Note: "renamed" is also skipped since its default implementation may call filelog.data() which will trigger the flag processor.
mercurial/verify.py
tests/test-verify.t
--- a/mercurial/verify.py
+++ b/mercurial/verify.py
@@ -44,16 +44,18 @@ class verifier(object):
         self.errors = 0
         self.warnings = 0
         self.havecl = len(repo.changelog) > 0
         self.havemf = len(repo.manifestlog._revlog) > 0
         self.revlogv1 = repo.changelog.version != revlog.REVLOGV0
         self.lrugetctx = util.lrucachefunc(repo.changectx)
         self.refersmf = False
         self.fncachewarned = False
+        # developer config: verify.skipflags
+        self.skipflags = repo.ui.configint('verify', 'skipflags')
 
     def warn(self, msg):
         self.ui.warn(msg + "\n")
         self.warnings += 1
 
     def err(self, linkrev, msg, filename=None):
         if linkrev is not None:
             self.badrevs.add(linkrev)
@@ -422,18 +424,22 @@ class verifier(object):
                 # (?): could be "- len(meta)" if the resolved content has
                 #      rename metadata
                 #
                 # Checks needed to be done:
                 #  1. length check: L1 == L2, in all cases.
                 #  2. hash check: depending on flag processor, we may need to
                 #     use either "text" (external), or "rawtext" (in revlog).
                 try:
-                    fl.read(n) # side effect: read content and do checkhash
-                    rp = fl.renamed(n)
+                    skipflags = self.skipflags
+                    if skipflags:
+                        skipflags &= fl.flags(i)
+                    if not skipflags:
+                        fl.read(n) # side effect: read content and do checkhash
+                        rp = fl.renamed(n)
                     # the "L1 == L2" check
                     l1 = fl.rawsize(i)
                     l2 = len(fl.revision(n, raw=True))
                     if l1 != l2:
                         self.err(lr, _("unpacked size is %s, %s expected") %
                                  (l2, l1), f)
                 except error.CensoredNodeError:
                     # experimental config: censor.policy
--- a/tests/test-verify.t
+++ b/tests/test-verify.t
@@ -312,8 +312,52 @@ test revlog format 0
   $ hg verify
   repository uses revlog format 0
   checking changesets
   checking manifests
   crosschecking files in changesets and manifests
   checking files
   1 files, 1 changesets, 1 total revisions
   $ cd ..
+
+test flag processor and skipflags
+
+  $ hg init skipflags
+  $ cd skipflags
+  $ cat >> .hg/hgrc <<EOF
+  > [extensions]
+  > flagprocesor=$RUNTESTDIR/flagprocessorext.py
+  > EOF
+  $ echo '[BASE64]content' > base64
+  $ hg commit -Aqm 'flag processor content' base64
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  1 files, 1 changesets, 1 total revisions
+
+  $ cat >> $TESTTMP/break-base64.py <<EOF
+  > from __future__ import absolute_import
+  > import base64
+  > base64.b64decode=lambda x: x
+  > EOF
+  $ cat >> .hg/hgrc <<EOF
+  > breakbase64=$TESTTMP/break-base64.py
+  > EOF
+
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+   base64@0: unpacking 794cee7777cb: integrity check failed on data/base64.i:0
+  1 files, 1 changesets, 1 total revisions
+  1 integrity errors encountered!
+  (first damaged changeset appears to be 0)
+  [1]
+  $ hg verify --config verify.skipflags=2147483647
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  1 files, 1 changesets, 1 total revisions
+