##// END OF EJS Templates
verify: check directory manifests...
Martin von Zweigbergk -
r28203:7297e9e1 default
parent child Browse files
Show More
@@ -325,6 +325,9 b' class manifestdict(object):'
325 325 def iteritems(self):
326 326 return (x[:2] for x in self._lm.iterentries())
327 327
328 def iterentries(self):
329 return self._lm.iterentries()
330
328 331 def text(self, usemanifestv2=False):
329 332 if usemanifestv2:
330 333 return _textv2(self._lm.iterentries())
@@ -920,7 +923,8 b' class manifest(revlog.revlog):'
920 923 return manifestdict(data)
921 924
922 925 def dirlog(self, dir):
923 assert self._treeondisk
926 if dir:
927 assert self._treeondisk
924 928 if dir not in self._dirlogcache:
925 929 self._dirlogcache[dir] = manifest(self.opener, dir,
926 930 self._dirlogcache)
@@ -945,6 +949,22 b' class manifest(revlog.revlog):'
945 949 d = mdiff.patchtext(self.revdiff(self.deltaparent(r), r))
946 950 return self._newmanifest(d)
947 951
952 def readshallowdelta(self, node):
953 '''For flat manifests, this is the same as readdelta(). For
954 treemanifests, this will read the delta for this revlog's directory,
955 without recursively reading subdirectory manifests. Instead, any
956 subdirectory entry will be reported as it appears in the manifests, i.e.
957 the subdirectory will be reported among files and distinguished only by
958 its 't' flag.'''
959 if not self._treeondisk:
960 return self.readdelta(node)
961 if self._usemanifestv2:
962 raise error.Abort(
963 "readshallowdelta() not implemented for manifestv2")
964 r = self.rev(node)
965 d = mdiff.patchtext(self.revdiff(self.deltaparent(r), r))
966 return manifestdict(d)
967
948 968 def readfast(self, node):
949 969 '''use the faster of readdelta or read
950 970
@@ -197,46 +197,73 b' class verifier(object):'
197 197 ui.progress(_('checking'), None)
198 198 return mflinkrevs, filelinkrevs
199 199
200 def _verifymanifest(self, mflinkrevs):
200 def _verifymanifest(self, mflinkrevs, dir=""):
201 201 repo = self.repo
202 202 ui = self.ui
203 mf = self.repo.manifest
203 mf = self.repo.manifest.dirlog(dir)
204 204
205 ui.status(_("checking manifests\n"))
205 if not dir:
206 self.ui.status(_("checking manifests\n"))
207
206 208 filenodes = {}
209 subdirnodes = {}
207 210 seen = {}
208 211 label = "manifest"
212 if dir:
213 label = dir
209 214 if self.refersmf:
210 215 # Do not check manifest if there are only changelog entries with
211 216 # null manifests.
212 217 self.checklog(mf, label, 0)
213 218 total = len(mf)
214 219 for i in mf:
215 ui.progress(_('checking'), i, total=total, unit=_('manifests'))
220 if not dir:
221 ui.progress(_('checking'), i, total=total, unit=_('manifests'))
216 222 n = mf.node(i)
217 223 lr = self.checkentry(mf, i, n, seen, mflinkrevs.get(n, []), label)
218 224 if n in mflinkrevs:
219 225 del mflinkrevs[n]
226 elif dir:
227 self.err(lr, _("%s not in parent-directory manifest") %
228 short(n), label)
220 229 else:
221 230 self.err(lr, _("%s not in changesets") % short(n), label)
222 231
223 232 try:
224 for f, fn in mf.readdelta(n).iteritems():
233 for f, fn, fl in mf.readshallowdelta(n).iterentries():
225 234 if not f:
226 self.err(lr, _("file without name in manifest"))
227 elif f != "/dev/null": # ignore this in very old repos
228 if _validpath(repo, f):
229 filenodes.setdefault(
230 _normpath(f), {}).setdefault(fn, lr)
235 self.err(lr, _("entry without name in manifest"))
236 elif f == "/dev/null": # ignore this in very old repos
237 continue
238 fullpath = dir + _normpath(f)
239 if not _validpath(repo, fullpath):
240 continue
241 if fl == 't':
242 subdirnodes.setdefault(fullpath + '/', {}).setdefault(
243 fn, []).append(lr)
244 else:
245 filenodes.setdefault(fullpath, {}).setdefault(fn, lr)
231 246 except Exception as inst:
232 247 self.exc(lr, _("reading delta %s") % short(n), inst, label)
233 ui.progress(_('checking'), None)
248 if not dir:
249 ui.progress(_('checking'), None)
234 250
235 251 if self.havemf:
236 252 for c, m in sorted([(c, m) for m in mflinkrevs
237 253 for c in mflinkrevs[m]]):
238 self.err(c, _("changeset refers to unknown revision %s") %
239 short(m), label)
254 if dir:
255 self.err(c, _("parent-directory manifest refers to unknown "
256 "revision %s") % short(m), label)
257 else:
258 self.err(c, _("changeset refers to unknown revision %s") %
259 short(m), label)
260
261 if not dir and subdirnodes:
262 self.ui.status(_("checking directory manifests\n"))
263 for subdir, linkrevs in subdirnodes.iteritems():
264 subdirfilenodes = self._verifymanifest(linkrevs, subdir)
265 for f, onefilenodes in subdirfilenodes.iteritems():
266 filenodes.setdefault(f, {}).update(onefilenodes)
240 267
241 268 return filenodes
242 269
@@ -471,6 +471,7 b' Verify works'
471 471 $ hg verify
472 472 checking changesets
473 473 checking manifests
474 checking directory manifests
474 475 crosschecking files in changesets and manifests
475 476 checking files
476 477 8 files, 3 changesets, 10 total revisions
@@ -503,6 +504,56 b' Rebuilt fncache includes dirlogs'
503 504 Finish first server
504 505 $ killdaemons.py
505 506
507 Back up the recently added revlogs
508 $ cp -r .hg/store .hg/store-newcopy
509
510 Verify reports missing dirlog
511 $ rm .hg/store/meta/b/00manifest.*
512 $ hg verify
513 checking changesets
514 checking manifests
515 checking directory manifests
516 0: empty or missing b/
517 b/@0: parent-directory manifest refers to unknown revision 67688a370455
518 b/@1: parent-directory manifest refers to unknown revision f38e85d334c5
519 b/@2: parent-directory manifest refers to unknown revision 99c9792fd4b0
520 crosschecking files in changesets and manifests
521 b/bar/fruits.txt@0: in changeset but not in manifest
522 b/bar/orange/fly/gnat.py@0: in changeset but not in manifest
523 b/bar/orange/fly/housefly.txt@0: in changeset but not in manifest
524 b/foo/apple/bees/flower.py@0: in changeset but not in manifest
525 checking files
526 8 files, 3 changesets, 10 total revisions
527 8 integrity errors encountered!
528 (first damaged changeset appears to be 0)
529 [1]
530 $ cp -rT .hg/store-newcopy .hg/store
531
532 Verify reports missing dirlog entry
533 $ mv -f .hg/store-copy/meta/b/00manifest.* .hg/store/meta/b/
534 $ hg verify
535 checking changesets
536 checking manifests
537 checking directory manifests
538 b/@1: parent-directory manifest refers to unknown revision f38e85d334c5
539 b/@2: parent-directory manifest refers to unknown revision 99c9792fd4b0
540 b/bar/@?: rev 1 points to unexpected changeset 1
541 b/bar/@?: 5e03c4ee5e4a not in parent-directory manifest
542 b/bar/@?: rev 2 points to unexpected changeset 2
543 b/bar/@?: 1b16940d66d6 not in parent-directory manifest
544 b/bar/orange/@?: rev 1 points to unexpected changeset 2
545 (expected None)
546 b/bar/orange/fly/@?: rev 1 points to unexpected changeset 2
547 (expected None)
548 crosschecking files in changesets and manifests
549 checking files
550 8 files, 3 changesets, 10 total revisions
551 2 warnings encountered!
552 8 integrity errors encountered!
553 (first damaged changeset appears to be 1)
554 [1]
555 $ cp -rT .hg/store-newcopy .hg/store
556
506 557 Test cloning a treemanifest repo over http.
507 558 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
508 559 $ cat hg.pid >> $DAEMON_PIDS
@@ -547,6 +598,7 b' Verify passes.'
547 598 $ hg verify
548 599 checking changesets
549 600 checking manifests
601 checking directory manifests
550 602 crosschecking files in changesets and manifests
551 603 checking files
552 604 8 files, 3 changesets, 10 total revisions
@@ -591,6 +643,7 b' Local clone with basicstore'
591 643 $ hg -R local-clone-basicstore verify
592 644 checking changesets
593 645 checking manifests
646 checking directory manifests
594 647 crosschecking files in changesets and manifests
595 648 checking files
596 649 8 files, 3 changesets, 10 total revisions
@@ -600,6 +653,7 b' Local clone with encodedstore'
600 653 $ hg -R local-clone-encodedstore verify
601 654 checking changesets
602 655 checking manifests
656 checking directory manifests
603 657 crosschecking files in changesets and manifests
604 658 checking files
605 659 8 files, 3 changesets, 10 total revisions
@@ -609,6 +663,7 b' Local clone with fncachestore'
609 663 $ hg -R local-clone-fncachestore verify
610 664 checking changesets
611 665 checking manifests
666 checking directory manifests
612 667 crosschecking files in changesets and manifests
613 668 checking files
614 669 8 files, 3 changesets, 10 total revisions
@@ -624,6 +679,7 b' Stream clone with basicstore'
624 679 $ hg -R stream-clone-basicstore verify
625 680 checking changesets
626 681 checking manifests
682 checking directory manifests
627 683 crosschecking files in changesets and manifests
628 684 checking files
629 685 8 files, 3 changesets, 10 total revisions
@@ -639,6 +695,7 b' Stream clone with encodedstore'
639 695 $ hg -R stream-clone-encodedstore verify
640 696 checking changesets
641 697 checking manifests
698 checking directory manifests
642 699 crosschecking files in changesets and manifests
643 700 checking files
644 701 8 files, 3 changesets, 10 total revisions
@@ -654,6 +711,7 b' Stream clone with fncachestore'
654 711 $ hg -R stream-clone-fncachestore verify
655 712 checking changesets
656 713 checking manifests
714 checking directory manifests
657 715 crosschecking files in changesets and manifests
658 716 checking files
659 717 8 files, 3 changesets, 10 total revisions
General Comments 0
You need to be logged in to leave comments. Login now