verify: also check dirstate
authorRaphaël Gomès <rgomes@octobus.net>
Mon, 02 May 2022 11:27:20 +0200
changeset 49826 c84844cd523a
parent 49825 2f2682f40ea0
child 49827 d09a57ce6fc4
verify: also check dirstate The dirstate already is capable of verifying its integrity (although v2 features are not yet checked), let's run that code in `hg verify`.
mercurial/debugcommands.py
mercurial/verify.py
tests/test-amend-subrepo.t
tests/test-basic.t
tests/test-censor.t
tests/test-commandserver.t
tests/test-fncache.t
tests/test-largefiles-wireproto.t
tests/test-largefiles.t
tests/test-lfconvert.t
tests/test-lfs.t
tests/test-narrow-clone-stream.t
tests/test-push.t
tests/test-repair-strip.t
tests/test-treemanifest.t
tests/test-verify.t
--- a/mercurial/debugcommands.py	Mon May 02 17:47:38 2022 +0200
+++ b/mercurial/debugcommands.py	Mon May 02 11:27:20 2022 +0200
@@ -87,6 +87,7 @@
     upgrade,
     url as urlmod,
     util,
+    verify,
     vfs as vfsmod,
     wireprotoframing,
     wireprotoserver,
@@ -554,15 +555,9 @@
 @command(b'debugcheckstate', [], b'')
 def debugcheckstate(ui, repo):
     """validate the correctness of the current dirstate"""
-    parent1, parent2 = repo.dirstate.parents()
-    m1 = repo[parent1].manifest()
-    m2 = repo[parent2].manifest()
-    errors = 0
-    for err in repo.dirstate.verify(m1, m2):
-        ui.warn(err)
-        errors += 1
+    errors = verify.verifier(repo)._verify_dirstate()
     if errors:
-        errstr = _(b".hg/dirstate inconsistent with current parent's manifest")
+        errstr = _(b"dirstate inconsistent with current parent's manifest")
         raise error.Abort(errstr)
 
 
--- a/mercurial/verify.py	Mon May 02 17:47:38 2022 +0200
+++ b/mercurial/verify.py	Mon May 02 11:27:20 2022 +0200
@@ -15,6 +15,7 @@
 from . import (
     error,
     pycompat,
+    requirements,
     revlog,
     util,
 )
@@ -210,6 +211,12 @@
         self._crosscheckfiles(filelinkrevs, filenodes)
         totalfiles, filerevisions = self._verifyfiles(filenodes, filelinkrevs)
 
+        if self.errors:
+            ui.warn(_(b"not checking dirstate because of previous errors\n"))
+            dirstate_errors = 0
+        else:
+            dirstate_errors = self._verify_dirstate()
+
         # final report
         ui.status(
             _(b"checked %d changesets with %d changes to %d files\n")
@@ -225,6 +232,11 @@
                 msg = _(b"(first damaged changeset appears to be %d)\n")
                 msg %= min(self.badrevs)
                 ui.warn(msg)
+            if dirstate_errors:
+                ui.warn(
+                    _(b"dirstate inconsistent with current parent's manifest\n")
+                )
+                ui.warn(_(b"%d dirstate errors\n") % dirstate_errors)
             return 1
         return 0
 
@@ -585,3 +597,25 @@
                 self._warn(_(b"warning: orphan data file '%s'") % f)
 
         return len(files), revisions
+
+    def _verify_dirstate(self):
+        """Check that the dirstate is consistent with the parent's manifest"""
+        repo = self.repo
+        ui = self.ui
+        ui.status(_(b"checking dirstate\n"))
+
+        parent1, parent2 = repo.dirstate.parents()
+        m1 = repo[parent1].manifest()
+        m2 = repo[parent2].manifest()
+        dirstate_errors = 0
+
+        is_narrow = requirements.NARROW_REQUIREMENT in repo.requirements
+        narrow_matcher = repo.narrowmatch() if is_narrow else None
+
+        for err in repo.dirstate.verify(m1, m2, narrow_matcher):
+            ui.error(err)
+            dirstate_errors += 1
+
+        if dirstate_errors:
+            self.errors += dirstate_errors
+        return dirstate_errors
--- a/tests/test-amend-subrepo.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-amend-subrepo.t	Mon May 02 11:27:20 2022 +0200
@@ -190,6 +190,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 5 changesets with 12 changes to 4 files
   checking subrepo links
   subrepo 't' not found in revision 04aa62396ec6
--- a/tests/test-basic.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-basic.t	Mon May 02 11:27:20 2022 +0200
@@ -121,6 +121,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 1 changesets with 1 changes to 1 files
 
 Repository root:
--- a/tests/test-censor.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-censor.t	Mon May 02 11:27:20 2022 +0200
@@ -175,6 +175,7 @@
   checking files
    target@1: censored file data
    target@2: censored file data
+  not checking dirstate because of previous errors
   checked 5 changesets with 7 changes to 2 files
   2 integrity errors encountered!
   (first damaged changeset appears to be 1)
--- a/tests/test-commandserver.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-commandserver.t	Mon May 02 11:27:20 2022 +0200
@@ -541,6 +541,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 2 changesets with 2 changes to 1 files
   $ hg revert --no-backup -aq
 
@@ -825,6 +826,7 @@
   message: '\xa6Ditem@Cpos\xf6EtopicMcrosscheckingEtotal\xf6DtypeHprogressDunit@'
   message: '\xa2DdataOchecking files\nDtypeFstatus'
   message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@'
+  message: '\xa2DdataRchecking dirstate\nDtypeFstatus'
   message: '\xa2DdataX/checked 0 changesets with 0 changes to 0 files\nDtypeFstatus'
 
   >>> from hgclient import checkwith, readchannel, runcommand, stringio
--- a/tests/test-fncache.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-fncache.t	Mon May 02 11:27:20 2022 +0200
@@ -61,6 +61,7 @@
    warning: revlog 'data/a.i' not in fncache!
    warning: revlog 'data/a.i.hg/c.i' not in fncache!
    warning: revlog 'data/a.i/b.i' not in fncache!
+  checking dirstate
   checked 3 changesets with 3 changes to 3 files
   3 warnings encountered!
   hint: run "hg debugrebuildfncache" to recover from corrupt fncache
@@ -349,6 +350,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 1 changesets with 1 changes to 1 files
   $ cat .hg/store/fncache
   data/y.i
--- a/tests/test-largefiles-wireproto.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-largefiles-wireproto.t	Mon May 02 11:27:20 2022 +0200
@@ -242,6 +242,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 1 changesets with 1 changes to 1 files
   searching 1 changesets for largefiles
   changeset 0:cf03e5bb9936: f1 missing
--- a/tests/test-largefiles.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-largefiles.t	Mon May 02 11:27:20 2022 +0200
@@ -1545,6 +1545,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 10 changesets with 28 changes to 10 files
   searching 1 changesets for largefiles
   verified existence of 3 revisions of 3 largefiles
--- a/tests/test-lfconvert.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-lfconvert.t	Mon May 02 11:27:20 2022 +0200
@@ -345,6 +345,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 8 changesets with 13 changes to 9 files
   searching 7 changesets for largefiles
   changeset 0:d4892ec57ce2: large references missing $TESTTMP/largefiles-repo-hg/.hg/largefiles/2e000fa7e85759c7f4c254d4d9c33ef481e459a7
--- a/tests/test-lfs.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-lfs.t	Mon May 02 11:27:20 2022 +0200
@@ -789,6 +789,7 @@
   checking files
    l@1: unpacking 46a2f24864bc: integrity check failed on l:0
    large@0: unpacking 2c531e0992ff: integrity check failed on large:0
+  not checking dirstate because of previous errors
   checked 5 changesets with 10 changes to 4 files
   2 integrity errors encountered!
   (first damaged changeset appears to be 0)
@@ -851,6 +852,7 @@
   checking files
   lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
   lfs blob sha256:66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e renamed large -> l
+  checking dirstate
   checked 5 changesets with 10 changes to 4 files
 
 Verify will not try to download lfs blobs, if told not to by the config option
@@ -865,6 +867,7 @@
   checking files
   lfs: found 22f66a3fc0b9bf3f012c814303995ec07099b3a9ce02a7af84b5970811074a3b in the local lfs store
   lfs blob sha256:66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e renamed large -> l
+  checking dirstate
   checked 5 changesets with 10 changes to 4 files
 
 Verify will copy/link all lfs objects into the local store that aren't already
@@ -885,6 +888,7 @@
   lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
   lfs: adding b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c to the usercache
   lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
+  checking dirstate
   checked 5 changesets with 10 changes to 4 files
 
 Verify will not copy/link a corrupted file from the usercache into the local
@@ -902,6 +906,7 @@
    large@0: unpacking 2c531e0992ff: integrity check failed on large:0
   lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
   lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
+  not checking dirstate because of previous errors
   checked 5 changesets with 10 changes to 4 files
   2 integrity errors encountered!
   (first damaged changeset appears to be 0)
@@ -917,6 +922,7 @@
   lfs: found 66100b384bf761271b407d79fc30cdd0554f3b2c5d944836e936d584b88ce88e in the local lfs store
   lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
   lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
+  checking dirstate
   checked 5 changesets with 10 changes to 4 files
 
 Damaging a file required by the update destination fails the update.
@@ -943,6 +949,7 @@
   checking files
    l@1: unpacking 46a2f24864bc: integrity check failed on l:0
    large@0: unpacking 2c531e0992ff: integrity check failed on large:0
+  not checking dirstate because of previous errors
   checked 5 changesets with 10 changes to 4 files
   2 integrity errors encountered!
   (first damaged changeset appears to be 0)
@@ -972,6 +979,7 @@
    large@0: unpacking 2c531e0992ff: integrity check failed on large:0
   lfs: found 89b6070915a3d573ff3599d1cda305bc5e38549b15c4847ab034169da66e1ca8 in the local lfs store
   lfs: found b1a6ea88da0017a0e77db139a54618986e9a2489bee24af9fe596de9daac498c in the local lfs store
+  not checking dirstate because of previous errors
   checked 5 changesets with 10 changes to 4 files
   2 integrity errors encountered!
   (first damaged changeset appears to be 0)
--- a/tests/test-narrow-clone-stream.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-narrow-clone-stream.t	Mon May 02 11:27:20 2022 +0200
@@ -101,4 +101,5 @@
   checking directory manifests (tree !)
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 40 changesets with 1 changes to 1 files
--- a/tests/test-push.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-push.t	Mon May 02 11:27:20 2022 +0200
@@ -141,6 +141,7 @@
 
   $ hg verify -q
    beta@1: dddc47b3ba30 not in manifests
+  not checking dirstate because of previous errors
   1 integrity errors encountered!
   (first damaged changeset appears to be 1)
   [1]
@@ -171,6 +172,7 @@
 
   $ hg verify -q
    beta@1: manifest refers to unknown revision dddc47b3ba30
+  not checking dirstate because of previous errors
   1 integrity errors encountered!
   (first damaged changeset appears to be 1)
   [1]
--- a/tests/test-repair-strip.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-repair-strip.t	Mon May 02 11:27:20 2022 +0200
@@ -66,6 +66,7 @@
    (expected 1)
    b@?: 736c29771fba not in manifests
   warning: orphan data file 'data/c.i'
+  not checking dirstate because of previous errors
   checked 2 changesets with 3 changes to 2 files
   2 warnings encountered!
   2 integrity errors encountered!
@@ -79,6 +80,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 2 changesets with 2 changes to 2 files
   $ teststrip 0 2 r .hg/store/data/b.i
   % before update 0, strip 2
@@ -93,6 +95,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 4 changesets with 4 changes to 3 files
   % journal contents
   (no journal)
@@ -124,6 +127,7 @@
    b@?: rev 1 points to nonexistent changeset 2
    (expected 1)
    c@?: rev 0 points to nonexistent changeset 3
+  not checking dirstate because of previous errors
   checked 2 changesets with 4 changes to 3 files
   1 warnings encountered!
   7 integrity errors encountered!
@@ -138,6 +142,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 2 changesets with 2 changes to 2 files
 
   $ cd ..
--- a/tests/test-treemanifest.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-treemanifest.t	Mon May 02 11:27:20 2022 +0200
@@ -619,6 +619,7 @@
    b/bar/orange/fly/housefly.txt@0: in changeset but not in manifest
    b/foo/apple/bees/flower.py@0: in changeset but not in manifest
   checking files
+  not checking dirstate because of previous errors
   checked 4 changesets with 18 changes to 8 files
   6 warnings encountered! (reporevlogstore !)
   9 integrity errors encountered!
@@ -644,6 +645,7 @@
    (expected None)
   crosschecking files in changesets and manifests
   checking files
+  not checking dirstate because of previous errors
   checked 4 changesets with 18 changes to 8 files
   2 warnings encountered!
   8 integrity errors encountered!
--- a/tests/test-verify.t	Mon May 02 17:47:38 2022 +0200
+++ b/tests/test-verify.t	Mon May 02 11:27:20 2022 +0200
@@ -20,6 +20,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 1 changesets with 3 changes to 3 files
 
 verify with journal
@@ -31,6 +32,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 1 changesets with 3 changes to 3 files
   $ rm .hg/store/journal
 
@@ -55,6 +57,7 @@
    warning: revlog 'data/bar.txt.i' not in fncache!
    0: empty or missing bar.txt
    bar.txt@0: manifest refers to unknown revision 256559129457
+  not checking dirstate because of previous errors
   checked 1 changesets with 0 changes to 3 files
   3 warnings encountered!
   hint: run "hg debugrebuildfncache" to recover from corrupt fncache
@@ -83,6 +86,7 @@
    0: empty or missing changelog
    manifest@0: d0b6632564d4 not in changesets
    manifest@1: 941fc4534185 not in changesets
+  not checking dirstate because of previous errors
   3 integrity errors encountered!
   (first damaged changeset appears to be 0)
   [1]
@@ -93,6 +97,7 @@
   $ rm .hg/store/00manifest.*
   $ hg verify -q
    0: empty or missing manifest
+  not checking dirstate because of previous errors
   1 integrity errors encountered!
   (first damaged changeset appears to be 0)
   [1]
@@ -106,6 +111,7 @@
    0: empty or missing file
    file@0: manifest refers to unknown revision 362fef284ce2
    file@1: manifest refers to unknown revision c10f2164107d
+  not checking dirstate because of previous errors
   1 warnings encountered!
   hint: run "hg debugrebuildfncache" to recover from corrupt fncache
   3 integrity errors encountered!
@@ -119,7 +125,13 @@
   $ rm .hg/store/00manifest.*
   $ hg verify -q
   warning: orphan data file 'data/file.i'
+  warning: ignoring unknown working parent c5ddb05ab828!
+  file marked as tracked in p1 but not in manifest1
   1 warnings encountered!
+  1 integrity errors encountered!
+  dirstate inconsistent with current parent's manifest
+  1 dirstate errors
+  [1]
   $ cp -R .hg/store-full/. .hg/store
 
 Entire changelog and filelog missing
@@ -134,6 +146,7 @@
    ?: empty or missing file
    file@0: manifest refers to unknown revision 362fef284ce2
    file@1: manifest refers to unknown revision c10f2164107d
+  not checking dirstate because of previous errors
   1 warnings encountered!
   hint: run "hg debugrebuildfncache" to recover from corrupt fncache
   6 integrity errors encountered!
@@ -149,6 +162,7 @@
    0: empty or missing manifest
    warning: revlog 'data/file.i' not in fncache!
    0: empty or missing file
+  not checking dirstate because of previous errors
   1 warnings encountered!
   hint: run "hg debugrebuildfncache" to recover from corrupt fncache
   2 integrity errors encountered!
@@ -164,6 +178,7 @@
    manifest@?: 941fc4534185 not in changesets
    file@?: rev 1 points to nonexistent changeset 1
    (expected 0)
+  not checking dirstate because of previous errors
   1 warnings encountered!
   3 integrity errors encountered!
   [1]
@@ -175,6 +190,7 @@
   $ hg verify -q
    manifest@1: changeset refers to unknown revision 941fc4534185
    file@1: c10f2164107d not in manifests
+  not checking dirstate because of previous errors
   2 integrity errors encountered!
   (first damaged changeset appears to be 1)
   [1]
@@ -185,6 +201,7 @@
   $ cp -f .hg/store-partial/data/file.* .hg/store/data
   $ hg verify -q
    file@1: manifest refers to unknown revision c10f2164107d
+  not checking dirstate because of previous errors
   1 integrity errors encountered!
   (first damaged changeset appears to be 1)
   [1]
@@ -198,6 +215,7 @@
    file@?: rev 1 points to nonexistent changeset 1
    (expected 0)
    file@?: c10f2164107d not in manifests
+  not checking dirstate because of previous errors
   1 warnings encountered!
   2 integrity errors encountered!
   [1]
@@ -211,6 +229,7 @@
    manifest@?: rev 1 points to nonexistent changeset 1
    manifest@?: 941fc4534185 not in changesets
    file@?: manifest refers to unknown revision c10f2164107d
+  not checking dirstate because of previous errors
   3 integrity errors encountered!
   [1]
   $ cp -R .hg/store-full/. .hg/store
@@ -221,6 +240,7 @@
   $ cp -f .hg/store-partial/data/file.* .hg/store/data
   $ hg verify -q
    manifest@1: changeset refers to unknown revision 941fc4534185
+  not checking dirstate because of previous errors
   1 integrity errors encountered!
   (first damaged changeset appears to be 1)
   [1]
@@ -236,6 +256,7 @@
    manifest@?: d0b6632564d4 not in changesets
    file@?: rev 0 points to unexpected changeset 0
    (expected 1)
+  not checking dirstate because of previous errors
   1 warnings encountered!
   4 integrity errors encountered!
   (first damaged changeset appears to be 0)
@@ -249,6 +270,7 @@
   $ hg verify -q
    manifest@0: reading delta d0b6632564d4: * (glob)
    file@0: 362fef284ce2 not in manifests
+  not checking dirstate because of previous errors
   2 integrity errors encountered!
   (first damaged changeset appears to be 0)
   [1]
@@ -260,6 +282,7 @@
   >   2> /dev/null
   $ hg verify -q
    file@0: unpacking 362fef284ce2: * (glob)
+  not checking dirstate because of previous errors
   1 integrity errors encountered!
   (first damaged changeset appears to be 0)
   [1]
@@ -290,6 +313,7 @@
   $ hg verify -q
    a@1: broken revlog! (index a is corrupted)
   warning: orphan data file 'data/a.i'
+  not checking dirstate because of previous errors
   1 warnings encountered!
   1 integrity errors encountered!
   (first damaged changeset appears to be 1)
@@ -307,6 +331,7 @@
   checking manifests
   crosschecking files in changesets and manifests
   checking files
+  checking dirstate
   checked 1 changesets with 1 changes to 1 files
   $ cd ..
 
@@ -332,6 +357,7 @@
 
   $ hg verify -q
    base64@0: unpacking 794cee7777cb: integrity check failed on base64:0
+  not checking dirstate because of previous errors
   1 integrity errors encountered!
   (first damaged changeset appears to be 0)
   [1]