[PATCH 18 of 18 "] verify: also check full manifest validity during verify runs [RFC]

Pierre-Yves David pierre-yves.david at ens-lyon.org
Wed Mar 6 11:29:34 EST 2019


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at octobus.net>
# Date 1551881213 -3600
#      Wed Mar 06 15:06:53 2019 +0100
# Node ID 1e978412397a4fe629dfa9420b1a7773dc936b19
# Parent  92091b3de1503bf562fe5bf2b544781f92702738
# EXP-Topic verify
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 1e978412397a
verify: also check full manifest validity during verify runs [RFC]

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 tried 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`. We might want to
put it behind a new flag like `--full`. Another way to look at this would be to
offer a `--quick` flag that disable it. In particular, since `hg recover` runs
verify, this could impact users.

diff --git a/mercurial/verify.py b/mercurial/verify.py
--- a/mercurial/verify.py
+++ b/mercurial/verify.py
@@ -330,6 +330,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:
+                try:
+                    # Manifest not in sorted order are invalid and will crash
+                    # Mercurial. We restore each entry to make sure they are
+                    # ordered.
+                    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()
 


More information about the Mercurial-devel mailing list