changeset 47817:855463b5fe49 stable

debugcommands: add a `--paranoid` option to `debug-repair-issue-6528` See justification inline. Differential Revision: https://phab.mercurial-scm.org/D11263
author Raphaël Gomès <rgomes@octobus.net>
date Fri, 06 Aug 2021 12:10:36 +0200
parents 32e21ac3adb1
children 5b046c2e3000
files mercurial/debugcommands.py mercurial/revlogutils/rewrite.py tests/test-completion.t tests/test-issue6528.t
diffstat 4 files changed, 47 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/debugcommands.py	Thu Aug 05 17:00:03 2021 +0200
+++ b/mercurial/debugcommands.py	Fri Aug 06 12:10:36 2021 +0200
@@ -1470,6 +1470,12 @@
             _(b'repair revisions listed in this report file'),
             _(b'FILE'),
         ),
+        (
+            b'',
+            b'paranoid',
+            False,
+            _(b'check that both detection methods do the same thing'),
+        ),
     ]
     + cmdutil.dryrunopts,
 )
@@ -1491,6 +1497,11 @@
     Note that this does *not* mean that this repairs future affected revisions,
     that needs a separate fix at the exchange level that hasn't been written yet
     (as of 5.9rc0).
+
+    There is a `--paranoid` flag to test that the fast implementation is correct
+    by checking it against the slow implementation. Since this matter is quite
+    urgent and testing every edge-case is probably quite costly, we use this
+    method to test on large repositories as a fuzzing method of sorts.
     """
     cmdutil.check_incompatible_arguments(
         opts, 'to_report', ['from_report', 'dry_run']
@@ -1498,6 +1509,7 @@
     dry_run = opts.get('dry_run')
     to_report = opts.get('to_report')
     from_report = opts.get('from_report')
+    paranoid = opts.get('paranoid')
     # TODO maybe add filelog pattern and revision pattern parameters to help
     # narrow down the search for users that know what they're looking for?
 
@@ -1506,7 +1518,12 @@
         raise error.Abort(_(msg))
 
     rewrite.repair_issue6528(
-        ui, repo, dry_run=dry_run, to_report=to_report, from_report=from_report
+        ui,
+        repo,
+        dry_run=dry_run,
+        to_report=to_report,
+        from_report=from_report,
+        paranoid=paranoid,
     )
 
 
--- a/mercurial/revlogutils/rewrite.py	Thu Aug 05 17:00:03 2021 +0200
+++ b/mercurial/revlogutils/rewrite.py	Fri Aug 06 12:10:36 2021 +0200
@@ -672,7 +672,9 @@
                 _reorder_filelog_parents(repo, fl, sorted(to_fix))
 
 
-def repair_issue6528(ui, repo, dry_run=False, to_report=None, from_report=None):
+def repair_issue6528(
+    ui, repo, dry_run=False, to_report=None, from_report=None, paranoid=False
+):
     from .. import store  # avoid cycle
 
     @contextlib.contextmanager
@@ -719,6 +721,12 @@
                 affected = _is_revision_affected_fast(
                     repo, fl, filerev, metadata_cache
                 )
+                if paranoid:
+                    slow = _is_revision_affected(fl, filerev)
+                    if slow != affected:
+                        msg = _(b"paranoid check failed for '%s' at node %s")
+                        node = binascii.hexlify(fl.node(filerev))
+                        raise error.Abort(msg % (filename, node))
                 if affected:
                     msg = b"found affected revision %d for filelog '%s'\n"
                     ui.warn(msg % (filerev, path))
--- a/tests/test-completion.t	Thu Aug 05 17:00:03 2021 +0200
+++ b/tests/test-completion.t	Fri Aug 06 12:10:36 2021 +0200
@@ -267,7 +267,7 @@
   config: untrusted, exp-all-known, edit, local, source, shared, non-shared, global, template
   continue: dry-run
   copy: forget, after, at-rev, force, include, exclude, dry-run
-  debug-repair-issue6528: to-report, from-report, dry-run
+  debug-repair-issue6528: to-report, from-report, paranoid, dry-run
   debugancestor: 
   debugantivirusrunning: 
   debugapplystreamclonebundle: 
--- a/tests/test-issue6528.t	Thu Aug 05 17:00:03 2021 +0200
+++ b/tests/test-issue6528.t	Fri Aug 06 12:10:36 2021 +0200
@@ -220,6 +220,25 @@
        0       6 2a8d3833f2fb 000000000000 000000000000
        1       7 2a80419dfc31 2a8d3833f2fb 000000000000
 
+Test the --paranoid option
+  $ hg debug-repair-issue6528 --dry-run --paranoid
+  found affected revision 1 for filelog 'data/D.txt.i'
+  found affected revision 1 for filelog 'data/b.txt.i'
+  found affected revision 3 for filelog 'data/b.txt.i'
+  $ hg st
+  M D.txt
+  M b.txt
+  $ hg debugrevlogindex b.txt
+     rev linkrev nodeid       p1           p2
+       0       2 05b806ebe5ea 000000000000 000000000000
+       1       3 a58b36ad6b65 05b806ebe5ea 000000000000
+       2       6 216a5fe8b8ed 000000000000 000000000000
+       3       7 ea4f2f2463cc 216a5fe8b8ed 000000000000
+  $ hg debugrevlogindex D.txt
+     rev linkrev nodeid       p1           p2
+       0       6 2a8d3833f2fb 000000000000 000000000000
+       1       7 2a80419dfc31 2a8d3833f2fb 000000000000
+
 Run the fix
   $ hg debug-repair-issue6528
   found affected revision 1 for filelog 'data/D.txt.i'