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).iter |
|
|
233 | for f, fn, fl in mf.readshallowdelta(n).iterentries(): | |
|
225 | 234 | if not f: |
|
226 |
self.err(lr, _(" |
|
|
227 |
elif f |
|
|
228 |
|
|
|
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