##// END OF EJS Templates
verify: use similar language for missing manifest and file revisions...
Martin von Zweigbergk -
r28114:2a03a365 default
parent child Browse files
Show More
@@ -1,381 +1,381 b''
1 1 # verify.py - repository integrity checking for Mercurial
2 2 #
3 3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import os
11 11
12 12 from .i18n import _
13 13 from .node import (
14 14 nullid,
15 15 short,
16 16 )
17 17
18 18 from . import (
19 19 error,
20 20 revlog,
21 21 util,
22 22 )
23 23
24 24 def verify(repo):
25 25 with repo.lock():
26 26 return verifier(repo).verify()
27 27
28 28 def _normpath(f):
29 29 # under hg < 2.4, convert didn't sanitize paths properly, so a
30 30 # converted repo may contain repeated slashes
31 31 while '//' in f:
32 32 f = f.replace('//', '/')
33 33 return f
34 34
35 35 def _validpath(repo, path):
36 36 """Returns False if a path should NOT be treated as part of a repo.
37 37
38 38 For all in-core cases, this returns True, as we have no way for a
39 39 path to be mentioned in the history but not actually be
40 40 relevant. For narrow clones, this is important because many
41 41 filelogs will be missing, and changelog entries may mention
42 42 modified files that are outside the narrow scope.
43 43 """
44 44 return True
45 45
46 46 class verifier(object):
47 47 def __init__(self, repo):
48 48 self.repo = repo.unfiltered()
49 49 self.ui = repo.ui
50 50 self.badrevs = set()
51 51 self.errors = 0
52 52 self.warnings = 0
53 53 self.havecl = len(repo.changelog) > 0
54 54 self.havemf = len(repo.manifest) > 0
55 55 self.revlogv1 = repo.changelog.version != revlog.REVLOGV0
56 56 self.lrugetctx = util.lrucachefunc(repo.changectx)
57 57 self.refersmf = False
58 58 self.fncachewarned = False
59 59
60 60 def warn(self, msg):
61 61 self.ui.warn(msg + "\n")
62 62 self.warnings += 1
63 63
64 64 def err(self, linkrev, msg, filename=None):
65 65 if linkrev is not None:
66 66 self.badrevs.add(linkrev)
67 67 else:
68 68 linkrev = '?'
69 69 msg = "%s: %s" % (linkrev, msg)
70 70 if filename:
71 71 msg = "%s@%s" % (filename, msg)
72 72 self.ui.warn(" " + msg + "\n")
73 73 self.errors += 1
74 74
75 75 def exc(self, linkrev, msg, inst, filename=None):
76 76 if not str(inst):
77 77 inst = repr(inst)
78 78 self.err(linkrev, "%s: %s" % (msg, inst), filename)
79 79
80 80 def checklog(self, obj, name, linkrev):
81 81 if not len(obj) and (self.havecl or self.havemf):
82 82 self.err(linkrev, _("empty or missing %s") % name)
83 83 return
84 84
85 85 d = obj.checksize()
86 86 if d[0]:
87 87 self.err(None, _("data length off by %d bytes") % d[0], name)
88 88 if d[1]:
89 89 self.err(None, _("index contains %d extra bytes") % d[1], name)
90 90
91 91 if obj.version != revlog.REVLOGV0:
92 92 if not self.revlogv1:
93 93 self.warn(_("warning: `%s' uses revlog format 1") % name)
94 94 elif self.revlogv1:
95 95 self.warn(_("warning: `%s' uses revlog format 0") % name)
96 96
97 97 def checkentry(self, obj, i, node, seen, linkrevs, f):
98 98 lr = obj.linkrev(obj.rev(node))
99 99 if lr < 0 or (self.havecl and lr not in linkrevs):
100 100 if lr < 0 or lr >= len(self.repo.changelog):
101 101 msg = _("rev %d points to nonexistent changeset %d")
102 102 else:
103 103 msg = _("rev %d points to unexpected changeset %d")
104 104 self.err(None, msg % (i, lr), f)
105 105 if linkrevs:
106 106 if f and len(linkrevs) > 1:
107 107 try:
108 108 # attempt to filter down to real linkrevs
109 109 linkrevs = [l for l in linkrevs
110 110 if self.lrugetctx(l)[f].filenode() == node]
111 111 except Exception:
112 112 pass
113 113 self.warn(_(" (expected %s)") % " ".join(map(str, linkrevs)))
114 114 lr = None # can't be trusted
115 115
116 116 try:
117 117 p1, p2 = obj.parents(node)
118 118 if p1 not in seen and p1 != nullid:
119 119 self.err(lr, _("unknown parent 1 %s of %s") %
120 120 (short(p1), short(node)), f)
121 121 if p2 not in seen and p2 != nullid:
122 122 self.err(lr, _("unknown parent 2 %s of %s") %
123 123 (short(p2), short(node)), f)
124 124 except Exception as inst:
125 125 self.exc(lr, _("checking parents of %s") % short(node), inst, f)
126 126
127 127 if node in seen:
128 128 self.err(lr, _("duplicate revision %d (%d)") % (i, seen[node]), f)
129 129 seen[node] = i
130 130 return lr
131 131
132 132 def verify(self):
133 133 repo = self.repo
134 134
135 135 ui = repo.ui
136 136
137 137 if not repo.url().startswith('file:'):
138 138 raise error.Abort(_("cannot verify bundle or remote repos"))
139 139
140 140 if os.path.exists(repo.sjoin("journal")):
141 141 ui.warn(_("abandoned transaction found - run hg recover\n"))
142 142
143 143 if ui.verbose or not self.revlogv1:
144 144 ui.status(_("repository uses revlog format %d\n") %
145 145 (self.revlogv1 and 1 or 0))
146 146
147 147 mflinkrevs, filelinkrevs = self._verifychangelog()
148 148
149 149 filenodes = self._verifymanifest(mflinkrevs)
150 150 del mflinkrevs
151 151
152 152 self._crosscheckfiles(filelinkrevs, filenodes)
153 153
154 154 totalfiles, filerevisions = self._verifyfiles(filenodes, filelinkrevs)
155 155
156 156 ui.status(_("%d files, %d changesets, %d total revisions\n") %
157 157 (totalfiles, len(repo.changelog), filerevisions))
158 158 if self.warnings:
159 159 ui.warn(_("%d warnings encountered!\n") % self.warnings)
160 160 if self.fncachewarned:
161 161 ui.warn(_('hint: run "hg debugrebuildfncache" to recover from '
162 162 'corrupt fncache\n'))
163 163 if self.errors:
164 164 ui.warn(_("%d integrity errors encountered!\n") % self.errors)
165 165 if self.badrevs:
166 166 ui.warn(_("(first damaged changeset appears to be %d)\n")
167 167 % min(self.badrevs))
168 168 return 1
169 169
170 170 def _verifychangelog(self):
171 171 ui = self.ui
172 172 repo = self.repo
173 173 cl = repo.changelog
174 174
175 175 ui.status(_("checking changesets\n"))
176 176 mflinkrevs = {}
177 177 filelinkrevs = {}
178 178 seen = {}
179 179 self.checklog(cl, "changelog", 0)
180 180 total = len(repo)
181 181 for i in repo:
182 182 ui.progress(_('checking'), i, total=total, unit=_('changesets'))
183 183 n = cl.node(i)
184 184 self.checkentry(cl, i, n, seen, [i], "changelog")
185 185
186 186 try:
187 187 changes = cl.read(n)
188 188 if changes[0] != nullid:
189 189 mflinkrevs.setdefault(changes[0], []).append(i)
190 190 self.refersmf = True
191 191 for f in changes[3]:
192 192 if _validpath(repo, f):
193 193 filelinkrevs.setdefault(_normpath(f), []).append(i)
194 194 except Exception as inst:
195 195 self.refersmf = True
196 196 self.exc(i, _("unpacking changeset %s") % short(n), inst)
197 197 ui.progress(_('checking'), None)
198 198 return mflinkrevs, filelinkrevs
199 199
200 200 def _verifymanifest(self, mflinkrevs):
201 201 repo = self.repo
202 202 ui = self.ui
203 203 mf = self.repo.manifest
204 204
205 205 ui.status(_("checking manifests\n"))
206 206 filenodes = {}
207 207 seen = {}
208 208 if self.refersmf:
209 209 # Do not check manifest if there are only changelog entries with
210 210 # null manifests.
211 211 self.checklog(mf, "manifest", 0)
212 212 total = len(mf)
213 213 for i in mf:
214 214 ui.progress(_('checking'), i, total=total, unit=_('manifests'))
215 215 n = mf.node(i)
216 216 lr = self.checkentry(mf, i, n, seen, mflinkrevs.get(n, []),
217 217 "manifest")
218 218 if n in mflinkrevs:
219 219 del mflinkrevs[n]
220 220 else:
221 221 self.err(lr, _("%s not in changesets") % short(n), "manifest")
222 222
223 223 try:
224 224 for f, fn in mf.readdelta(n).iteritems():
225 225 if not f:
226 226 self.err(lr, _("file without name in manifest"))
227 227 elif f != "/dev/null": # ignore this in very old repos
228 228 if _validpath(repo, f):
229 229 filenodes.setdefault(
230 230 _normpath(f), {}).setdefault(fn, lr)
231 231 except Exception as inst:
232 232 self.exc(lr, _("reading delta %s") % short(n), inst)
233 233 ui.progress(_('checking'), None)
234 234
235 235 if self.havemf:
236 236 for c, m in sorted([(c, m) for m in mflinkrevs
237 237 for c in mflinkrevs[m]]):
238 238 self.err(c, _("changeset refers to unknown revision %s") %
239 239 short(m), "manifest")
240 240
241 241 return filenodes
242 242
243 243 def _crosscheckfiles(self, filelinkrevs, filenodes):
244 244 repo = self.repo
245 245 ui = self.ui
246 246 ui.status(_("crosschecking files in changesets and manifests\n"))
247 247
248 248 total = len(filelinkrevs) + len(filenodes)
249 249 count = 0
250 250 if self.havemf:
251 251 for f in sorted(filelinkrevs):
252 252 count += 1
253 253 ui.progress(_('crosschecking'), count, total=total)
254 254 if f not in filenodes:
255 255 lr = filelinkrevs[f][0]
256 256 self.err(lr, _("in changeset but not in manifest"), f)
257 257
258 258 if self.havecl:
259 259 for f in sorted(filenodes):
260 260 count += 1
261 261 ui.progress(_('crosschecking'), count, total=total)
262 262 if f not in filelinkrevs:
263 263 try:
264 264 fl = repo.file(f)
265 265 lr = min([fl.linkrev(fl.rev(n)) for n in filenodes[f]])
266 266 except Exception:
267 267 lr = None
268 268 self.err(lr, _("in manifest but not in changeset"), f)
269 269
270 270 ui.progress(_('crosschecking'), None)
271 271
272 272 def _verifyfiles(self, filenodes, filelinkrevs):
273 273 repo = self.repo
274 274 ui = self.ui
275 275 lrugetctx = self.lrugetctx
276 276 revlogv1 = self.revlogv1
277 277 havemf = self.havemf
278 278 ui.status(_("checking files\n"))
279 279
280 280 storefiles = set()
281 281 for f, f2, size in repo.store.datafiles():
282 282 if not f:
283 283 self.err(None, _("cannot decode filename '%s'") % f2)
284 284 elif (size > 0 or not revlogv1) and f.startswith('data/'):
285 285 storefiles.add(_normpath(f))
286 286
287 287 files = sorted(set(filenodes) | set(filelinkrevs))
288 288 total = len(files)
289 289 revisions = 0
290 290 for i, f in enumerate(files):
291 291 ui.progress(_('checking'), i, item=f, total=total)
292 292 try:
293 293 linkrevs = filelinkrevs[f]
294 294 except KeyError:
295 295 # in manifest but not in changelog
296 296 linkrevs = []
297 297
298 298 if linkrevs:
299 299 lr = linkrevs[0]
300 300 else:
301 301 lr = None
302 302
303 303 try:
304 304 fl = repo.file(f)
305 305 except error.RevlogError as e:
306 306 self.err(lr, _("broken revlog! (%s)") % e, f)
307 307 continue
308 308
309 309 for ff in fl.files():
310 310 try:
311 311 storefiles.remove(ff)
312 312 except KeyError:
313 313 self.warn(_(" warning: revlog '%s' not in fncache!") % ff)
314 314 self.fncachewarned = True
315 315
316 316 self.checklog(fl, f, lr)
317 317 seen = {}
318 318 rp = None
319 319 for i in fl:
320 320 revisions += 1
321 321 n = fl.node(i)
322 322 lr = self.checkentry(fl, i, n, seen, linkrevs, f)
323 323 if f in filenodes:
324 324 if havemf and n not in filenodes[f]:
325 325 self.err(lr, _("%s not in manifests") % (short(n)), f)
326 326 else:
327 327 del filenodes[f][n]
328 328
329 329 # verify contents
330 330 try:
331 331 l = len(fl.read(n))
332 332 rp = fl.renamed(n)
333 333 if l != fl.size(i):
334 334 if len(fl.revision(n)) != fl.size(i):
335 335 self.err(lr, _("unpacked size is %s, %s expected") %
336 336 (l, fl.size(i)), f)
337 337 except error.CensoredNodeError:
338 338 # experimental config: censor.policy
339 339 if ui.config("censor", "policy", "abort") == "abort":
340 340 self.err(lr, _("censored file data"), f)
341 341 except Exception as inst:
342 342 self.exc(lr, _("unpacking %s") % short(n), inst, f)
343 343
344 344 # check renames
345 345 try:
346 346 if rp:
347 347 if lr is not None and ui.verbose:
348 348 ctx = lrugetctx(lr)
349 349 found = False
350 350 for pctx in ctx.parents():
351 351 if rp[0] in pctx:
352 352 found = True
353 353 break
354 354 if not found:
355 355 self.warn(_("warning: copy source of '%s' not"
356 356 " in parents of %s") % (f, ctx))
357 357 fl2 = repo.file(rp[0])
358 358 if not len(fl2):
359 359 self.err(lr, _("empty or missing copy source "
360 360 "revlog %s:%s") % (rp[0], short(rp[1])), f)
361 361 elif rp[1] == nullid:
362 362 ui.note(_("warning: %s@%s: copy source"
363 363 " revision is nullid %s:%s\n")
364 364 % (f, lr, rp[0], short(rp[1])))
365 365 else:
366 366 fl2.rev(rp[1])
367 367 except Exception as inst:
368 368 self.exc(lr, _("checking rename of %s") % short(n), inst, f)
369 369
370 370 # cross-check
371 371 if f in filenodes:
372 372 fns = [(lr, n) for n, lr in filenodes[f].iteritems()]
373 373 for lr, node in sorted(fns):
374 self.err(lr, _("%s in manifests not found") % short(node),
375 f)
374 self.err(lr, _("manifest refers to unknown revision %s") %
375 short(node), f)
376 376 ui.progress(_('checking'), None)
377 377
378 378 for f in storefiles:
379 379 self.warn(_("warning: orphan revlog '%s'") % f)
380 380
381 381 return len(files), revisions
@@ -1,92 +1,92 b''
1 1 $ hg init test
2 2 $ cd test
3 3
4 4 $ cat > .hg/hgrc <<EOF
5 5 > [server]
6 6 > validate=1
7 7 > EOF
8 8
9 9 $ echo alpha > alpha
10 10 $ echo beta > beta
11 11 $ hg addr
12 12 adding alpha
13 13 adding beta
14 14 $ hg ci -m 1
15 15
16 16 $ cd ..
17 17 $ hg clone test test-clone
18 18 updating to branch default
19 19 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 20
21 21 Test spurious filelog entries:
22 22
23 23 $ cd test-clone
24 24 $ echo blah >> beta
25 25 $ cp .hg/store/data/beta.i tmp1
26 26 $ hg ci -m 2
27 27 $ cp .hg/store/data/beta.i tmp2
28 28 $ hg -q rollback
29 29 $ mv tmp2 .hg/store/data/beta.i
30 30 $ echo blah >> beta
31 31 $ hg ci -m '2 (corrupt)'
32 32
33 33 Expected to fail:
34 34
35 35 $ hg verify
36 36 checking changesets
37 37 checking manifests
38 38 crosschecking files in changesets and manifests
39 39 checking files
40 40 beta@1: dddc47b3ba30 not in manifests
41 41 2 files, 2 changesets, 4 total revisions
42 42 1 integrity errors encountered!
43 43 (first damaged changeset appears to be 1)
44 44 [1]
45 45
46 46 $ hg push
47 47 pushing to $TESTTMP/test (glob)
48 48 searching for changes
49 49 adding changesets
50 50 adding manifests
51 51 adding file changes
52 52 transaction abort!
53 53 rollback completed
54 54 abort: received spurious file revlog entry
55 55 [255]
56 56
57 57 $ hg -q rollback
58 58 $ mv tmp1 .hg/store/data/beta.i
59 59 $ echo beta > beta
60 60
61 61 Test missing filelog entries:
62 62
63 63 $ cp .hg/store/data/beta.i tmp
64 64 $ echo blah >> beta
65 65 $ hg ci -m '2 (corrupt)'
66 66 $ mv tmp .hg/store/data/beta.i
67 67
68 68 Expected to fail:
69 69
70 70 $ hg verify
71 71 checking changesets
72 72 checking manifests
73 73 crosschecking files in changesets and manifests
74 74 checking files
75 beta@1: dddc47b3ba30 in manifests not found
75 beta@1: manifest refers to unknown revision dddc47b3ba30
76 76 2 files, 2 changesets, 2 total revisions
77 77 1 integrity errors encountered!
78 78 (first damaged changeset appears to be 1)
79 79 [1]
80 80
81 81 $ hg push
82 82 pushing to $TESTTMP/test (glob)
83 83 searching for changes
84 84 adding changesets
85 85 adding manifests
86 86 adding file changes
87 87 transaction abort!
88 88 rollback completed
89 89 abort: missing file data for beta:dddc47b3ba30e54484720ce0f4f768a0f4b6efb9 - run hg verify
90 90 [255]
91 91
92 92 $ cd ..
@@ -1,319 +1,319 b''
1 1 prepare repo
2 2
3 3 $ hg init a
4 4 $ cd a
5 5 $ echo "some text" > FOO.txt
6 6 $ echo "another text" > bar.txt
7 7 $ echo "more text" > QUICK.txt
8 8 $ hg add
9 9 adding FOO.txt
10 10 adding QUICK.txt
11 11 adding bar.txt
12 12 $ hg ci -mtest1
13 13
14 14 verify
15 15
16 16 $ hg verify
17 17 checking changesets
18 18 checking manifests
19 19 crosschecking files in changesets and manifests
20 20 checking files
21 21 3 files, 1 changesets, 3 total revisions
22 22
23 23 verify with journal
24 24
25 25 $ touch .hg/store/journal
26 26 $ hg verify
27 27 abandoned transaction found - run hg recover
28 28 checking changesets
29 29 checking manifests
30 30 crosschecking files in changesets and manifests
31 31 checking files
32 32 3 files, 1 changesets, 3 total revisions
33 33 $ rm .hg/store/journal
34 34
35 35 introduce some bugs in repo
36 36
37 37 $ cd .hg/store/data
38 38 $ mv _f_o_o.txt.i X_f_o_o.txt.i
39 39 $ mv bar.txt.i xbar.txt.i
40 40 $ rm _q_u_i_c_k.txt.i
41 41
42 42 $ hg verify
43 43 checking changesets
44 44 checking manifests
45 45 crosschecking files in changesets and manifests
46 46 checking files
47 47 warning: revlog 'data/FOO.txt.i' not in fncache!
48 48 0: empty or missing FOO.txt
49 FOO.txt@0: f62022d3d590 in manifests not found
49 FOO.txt@0: manifest refers to unknown revision f62022d3d590
50 50 warning: revlog 'data/QUICK.txt.i' not in fncache!
51 51 0: empty or missing QUICK.txt
52 QUICK.txt@0: 88b857db8eba in manifests not found
52 QUICK.txt@0: manifest refers to unknown revision 88b857db8eba
53 53 warning: revlog 'data/bar.txt.i' not in fncache!
54 54 0: empty or missing bar.txt
55 bar.txt@0: 256559129457 in manifests not found
55 bar.txt@0: manifest refers to unknown revision 256559129457
56 56 3 files, 1 changesets, 0 total revisions
57 57 3 warnings encountered!
58 58 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
59 59 6 integrity errors encountered!
60 60 (first damaged changeset appears to be 0)
61 61 [1]
62 62
63 63 $ cd ../../..
64 64 $ cd ..
65 65
66 66 Set up a repo for testing missing revlog entries
67 67
68 68 $ hg init missing-entries
69 69 $ cd missing-entries
70 70 $ echo 0 > file
71 71 $ hg ci -Aqm0
72 72 $ cp -r .hg/store .hg/store-partial
73 73 $ echo 1 > file
74 74 $ hg ci -Aqm1
75 75 $ cp -r .hg/store .hg/store-full
76 76
77 77 Entire changelog missing
78 78
79 79 $ rm .hg/store/00changelog.*
80 80 $ hg verify -q
81 81 0: empty or missing changelog
82 82 manifest@0: d0b6632564d4 not in changesets
83 83 manifest@1: 941fc4534185 not in changesets
84 84 3 integrity errors encountered!
85 85 (first damaged changeset appears to be 0)
86 86 [1]
87 87 $ cp -r .hg/store-full/* .hg/store
88 88
89 89 Entire manifest log missing
90 90
91 91 $ rm .hg/store/00manifest.*
92 92 $ hg verify -q
93 93 0: empty or missing manifest
94 94 1 integrity errors encountered!
95 95 (first damaged changeset appears to be 0)
96 96 [1]
97 97 $ cp -r .hg/store-full/* .hg/store
98 98
99 99 Entire filelog missing
100 100
101 101 $ rm .hg/store/data/file.*
102 102 $ hg verify -q
103 103 warning: revlog 'data/file.i' not in fncache!
104 104 0: empty or missing file
105 file@0: 362fef284ce2 in manifests not found
106 file@1: c10f2164107d in manifests not found
105 file@0: manifest refers to unknown revision 362fef284ce2
106 file@1: manifest refers to unknown revision c10f2164107d
107 107 1 warnings encountered!
108 108 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
109 109 3 integrity errors encountered!
110 110 (first damaged changeset appears to be 0)
111 111 [1]
112 112 $ cp -r .hg/store-full/* .hg/store
113 113
114 114 Entire changelog and manifest log missing
115 115
116 116 $ rm .hg/store/00changelog.*
117 117 $ rm .hg/store/00manifest.*
118 118 $ hg verify -q
119 119 warning: orphan revlog 'data/file.i'
120 120 1 warnings encountered!
121 121 $ cp -r .hg/store-full/* .hg/store
122 122
123 123 Entire changelog and filelog missing
124 124
125 125 $ rm .hg/store/00changelog.*
126 126 $ rm .hg/store/data/file.*
127 127 $ hg verify -q
128 128 0: empty or missing changelog
129 129 manifest@0: d0b6632564d4 not in changesets
130 130 manifest@1: 941fc4534185 not in changesets
131 131 warning: revlog 'data/file.i' not in fncache!
132 132 ?: empty or missing file
133 file@0: 362fef284ce2 in manifests not found
134 file@1: c10f2164107d in manifests not found
133 file@0: manifest refers to unknown revision 362fef284ce2
134 file@1: manifest refers to unknown revision c10f2164107d
135 135 1 warnings encountered!
136 136 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
137 137 6 integrity errors encountered!
138 138 (first damaged changeset appears to be 0)
139 139 [1]
140 140 $ cp -r .hg/store-full/* .hg/store
141 141
142 142 Entire manifest log and filelog missing
143 143
144 144 $ rm .hg/store/00manifest.*
145 145 $ rm .hg/store/data/file.*
146 146 $ hg verify -q
147 147 0: empty or missing manifest
148 148 warning: revlog 'data/file.i' not in fncache!
149 149 0: empty or missing file
150 150 1 warnings encountered!
151 151 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
152 152 2 integrity errors encountered!
153 153 (first damaged changeset appears to be 0)
154 154 [1]
155 155 $ cp -r .hg/store-full/* .hg/store
156 156
157 157 Changelog missing entry
158 158
159 159 $ cp -f .hg/store-partial/00changelog.* .hg/store
160 160 $ hg verify -q
161 161 manifest@?: rev 1 points to nonexistent changeset 1
162 162 manifest@?: 941fc4534185 not in changesets
163 163 file@?: rev 1 points to nonexistent changeset 1
164 164 (expected 0)
165 165 1 warnings encountered!
166 166 3 integrity errors encountered!
167 167 [1]
168 168 $ cp -r .hg/store-full/* .hg/store
169 169
170 170 Manifest log missing entry
171 171
172 172 $ cp -f .hg/store-partial/00manifest.* .hg/store
173 173 $ hg verify -q
174 174 manifest@1: changeset refers to unknown revision 941fc4534185
175 175 file@1: c10f2164107d not in manifests
176 176 2 integrity errors encountered!
177 177 (first damaged changeset appears to be 1)
178 178 [1]
179 179 $ cp -r .hg/store-full/* .hg/store
180 180
181 181 Filelog missing entry
182 182
183 183 $ cp -f .hg/store-partial/data/file.* .hg/store/data
184 184 $ hg verify -q
185 file@1: c10f2164107d in manifests not found
185 file@1: manifest refers to unknown revision c10f2164107d
186 186 1 integrity errors encountered!
187 187 (first damaged changeset appears to be 1)
188 188 [1]
189 189 $ cp -r .hg/store-full/* .hg/store
190 190
191 191 Changelog and manifest log missing entry
192 192
193 193 $ cp -f .hg/store-partial/00changelog.* .hg/store
194 194 $ cp -f .hg/store-partial/00manifest.* .hg/store
195 195 $ hg verify -q
196 196 file@?: rev 1 points to nonexistent changeset 1
197 197 (expected 0)
198 198 file@?: c10f2164107d not in manifests
199 199 1 warnings encountered!
200 200 2 integrity errors encountered!
201 201 [1]
202 202 $ cp -r .hg/store-full/* .hg/store
203 203
204 204 Changelog and filelog missing entry
205 205
206 206 $ cp -f .hg/store-partial/00changelog.* .hg/store
207 207 $ cp -f .hg/store-partial/data/file.* .hg/store/data
208 208 $ hg verify -q
209 209 manifest@?: rev 1 points to nonexistent changeset 1
210 210 manifest@?: 941fc4534185 not in changesets
211 file@?: c10f2164107d in manifests not found
211 file@?: manifest refers to unknown revision c10f2164107d
212 212 3 integrity errors encountered!
213 213 [1]
214 214 $ cp -r .hg/store-full/* .hg/store
215 215
216 216 Manifest and filelog missing entry
217 217
218 218 $ cp -f .hg/store-partial/00manifest.* .hg/store
219 219 $ cp -f .hg/store-partial/data/file.* .hg/store/data
220 220 $ hg verify -q
221 221 manifest@1: changeset refers to unknown revision 941fc4534185
222 222 1 integrity errors encountered!
223 223 (first damaged changeset appears to be 1)
224 224 [1]
225 225 $ cp -r .hg/store-full/* .hg/store
226 226
227 227 Corrupt changelog base node to cause failure to read revision
228 228
229 229 $ printf abcd | dd conv=notrunc of=.hg/store/00changelog.i bs=1 seek=16 \
230 230 > 2> /dev/null
231 231 $ hg verify -q
232 232 0: unpacking changeset 08b1860757c2: * (glob)
233 233 manifest@?: rev 0 points to unexpected changeset 0
234 234 manifest@?: d0b6632564d4 not in changesets
235 235 file@?: rev 0 points to unexpected changeset 0
236 236 (expected 1)
237 237 1 warnings encountered!
238 238 4 integrity errors encountered!
239 239 (first damaged changeset appears to be 0)
240 240 [1]
241 241 $ cp -r .hg/store-full/* .hg/store
242 242
243 243 Corrupt manifest log base node to cause failure to read revision
244 244
245 245 $ printf abcd | dd conv=notrunc of=.hg/store/00manifest.i bs=1 seek=16 \
246 246 > 2> /dev/null
247 247 $ hg verify -q
248 248 manifest@0: reading delta d0b6632564d4: * (glob)
249 249 file@0: 362fef284ce2 not in manifests
250 250 2 integrity errors encountered!
251 251 (first damaged changeset appears to be 0)
252 252 [1]
253 253 $ cp -r .hg/store-full/* .hg/store
254 254
255 255 Corrupt filelog base node to cause failure to read revision
256 256
257 257 $ printf abcd | dd conv=notrunc of=.hg/store/data/file.i bs=1 seek=16 \
258 258 > 2> /dev/null
259 259 $ hg verify -q
260 260 file@0: unpacking 362fef284ce2: * (glob)
261 261 1 integrity errors encountered!
262 262 (first damaged changeset appears to be 0)
263 263 [1]
264 264 $ cp -r .hg/store-full/* .hg/store
265 265
266 266 $ cd ..
267 267
268 268 test changelog without a manifest
269 269
270 270 $ hg init b
271 271 $ cd b
272 272 $ hg branch foo
273 273 marked working directory as branch foo
274 274 (branches are permanent and global, did you want a bookmark?)
275 275 $ hg ci -m branchfoo
276 276 $ hg verify
277 277 checking changesets
278 278 checking manifests
279 279 crosschecking files in changesets and manifests
280 280 checking files
281 281 0 files, 1 changesets, 0 total revisions
282 282
283 283 test revlog corruption
284 284
285 285 $ touch a
286 286 $ hg add a
287 287 $ hg ci -m a
288 288
289 289 $ echo 'corrupted' > b
290 290 $ dd if=.hg/store/data/a.i of=start bs=1 count=20 2>/dev/null
291 291 $ cat start b > .hg/store/data/a.i
292 292
293 293 $ hg verify
294 294 checking changesets
295 295 checking manifests
296 296 crosschecking files in changesets and manifests
297 297 checking files
298 298 a@1: broken revlog! (index data/a.i is corrupted)
299 299 warning: orphan revlog 'data/a.i'
300 300 1 files, 2 changesets, 0 total revisions
301 301 1 warnings encountered!
302 302 1 integrity errors encountered!
303 303 (first damaged changeset appears to be 1)
304 304 [1]
305 305
306 306 $ cd ..
307 307
308 308 test revlog format 0
309 309
310 310 $ revlog-formatv0.py
311 311 $ cd formatv0
312 312 $ hg verify
313 313 repository uses revlog format 0
314 314 checking changesets
315 315 checking manifests
316 316 crosschecking files in changesets and manifests
317 317 checking files
318 318 1 files, 1 changesets, 1 total revisions
319 319 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now