Patchwork [4,of,4,V2] verify: also check full manifest validity during verify runs

login
register
mail settings
Submitter Pierre-Yves David
Date April 17, 2019, 10:49 a.m.
Message ID <6fc17babf069a54c9e02.1555498163@nodosa.octopoid.net>
Download mbox | patch
Permalink /patch/39685/
State Superseded
Headers show

Comments

Pierre-Yves David - April 17, 2019, 10:49 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@octobus.net>
# Date 1551881213 -3600
#      Wed Mar 06 15:06:53 2019 +0100
# Node ID 6fc17babf069a54c9e02e8e13aa36133468c641b
# Parent  9bec7491e9b4cabdfa4d264e5213b1f416ec2607
# EXP-Topic verify
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 6fc17babf069
verify: also check full manifest validity during verify runs

Before this changes, `hg verify` only checked if a manifest revision existed and
referenced the proper files. However it never checked the manifest revision
content itself.

Mercurial is expecting manifest entries to be sorted and will crash otherwise.
Since `hg verify` did not attempted a full restoration of manifest entry, it
could ignore this kind of corruption.

This new check significantly increases the cost of a `hg verify` run. This
especially affects large repository not using `sparse-revlog`. For now, this is
hidden behind the `--full` experimental flag.

Patch

diff --git a/mercurial/verify.py b/mercurial/verify.py
--- a/mercurial/verify.py
+++ b/mercurial/verify.py
@@ -337,6 +337,16 @@  class verifier(object):
                         filenodes.setdefault(fullpath, {}).setdefault(fn, lr)
             except Exception as inst:
                 self._exc(lr, _("reading delta %s") % short(n), inst, label)
+            if not dir and self._level >= VERIFY_FULL:
+                try:
+                    # Various issues can affect manifest. So we read each full
+                    # text from storage. This triggers the checks from the core
+                    # code (eg: hash verification, filename are ordered, etc.)
+                    mfdelta = mfl.get(dir, n).read()
+                except Exception as inst:
+                    self._exc(lr, _("reading full manifest %s") % short(n),
+                              inst, label)
+
         if not dir:
             progress.complete()