##// END OF EJS Templates
verify: drop "revlog" from warning message...
Gregory Szorc -
r37428:a6651f5e default
parent child Browse files
Show More
@@ -1,487 +1,487 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 pycompat,
21 21 revlog,
22 22 scmutil,
23 23 util,
24 24 )
25 25
26 26 def verify(repo):
27 27 with repo.lock():
28 28 return verifier(repo).verify()
29 29
30 30 def _normpath(f):
31 31 # under hg < 2.4, convert didn't sanitize paths properly, so a
32 32 # converted repo may contain repeated slashes
33 33 while '//' in f:
34 34 f = f.replace('//', '/')
35 35 return f
36 36
37 37 class verifier(object):
38 38 # The match argument is always None in hg core, but e.g. the narrowhg
39 39 # extension will pass in a matcher here.
40 40 def __init__(self, repo, match=None):
41 41 self.repo = repo.unfiltered()
42 42 self.ui = repo.ui
43 43 self.match = match or scmutil.matchall(repo)
44 44 self.badrevs = set()
45 45 self.errors = 0
46 46 self.warnings = 0
47 47 self.havecl = len(repo.changelog) > 0
48 48 self.havemf = len(repo.manifestlog._revlog) > 0
49 49 self.revlogv1 = repo.changelog.version != revlog.REVLOGV0
50 50 self.lrugetctx = util.lrucachefunc(repo.__getitem__)
51 51 self.refersmf = False
52 52 self.fncachewarned = False
53 53 # developer config: verify.skipflags
54 54 self.skipflags = repo.ui.configint('verify', 'skipflags')
55 55
56 56 def warn(self, msg):
57 57 self.ui.warn(msg + "\n")
58 58 self.warnings += 1
59 59
60 60 def err(self, linkrev, msg, filename=None):
61 61 if linkrev is not None:
62 62 self.badrevs.add(linkrev)
63 63 linkrev = "%d" % linkrev
64 64 else:
65 65 linkrev = '?'
66 66 msg = "%s: %s" % (linkrev, msg)
67 67 if filename:
68 68 msg = "%s@%s" % (filename, msg)
69 69 self.ui.warn(" " + msg + "\n")
70 70 self.errors += 1
71 71
72 72 def exc(self, linkrev, msg, inst, filename=None):
73 73 fmsg = pycompat.bytestr(inst)
74 74 if not fmsg:
75 75 fmsg = pycompat.byterepr(inst)
76 76 self.err(linkrev, "%s: %s" % (msg, fmsg), filename)
77 77
78 78 def checklog(self, obj, name, linkrev):
79 79 if not len(obj) and (self.havecl or self.havemf):
80 80 self.err(linkrev, _("empty or missing %s") % name)
81 81 return
82 82
83 83 d = obj.checksize()
84 84 if d[0]:
85 85 self.err(None, _("data length off by %d bytes") % d[0], name)
86 86 if d[1]:
87 87 self.err(None, _("index contains %d extra bytes") % d[1], name)
88 88
89 89 if obj.version != revlog.REVLOGV0:
90 90 if not self.revlogv1:
91 91 self.warn(_("warning: `%s' uses revlog format 1") % name)
92 92 elif self.revlogv1:
93 93 self.warn(_("warning: `%s' uses revlog format 0") % name)
94 94
95 95 def checkentry(self, obj, i, node, seen, linkrevs, f):
96 96 lr = obj.linkrev(obj.rev(node))
97 97 if lr < 0 or (self.havecl and lr not in linkrevs):
98 98 if lr < 0 or lr >= len(self.repo.changelog):
99 99 msg = _("rev %d points to nonexistent changeset %d")
100 100 else:
101 101 msg = _("rev %d points to unexpected changeset %d")
102 102 self.err(None, msg % (i, lr), f)
103 103 if linkrevs:
104 104 if f and len(linkrevs) > 1:
105 105 try:
106 106 # attempt to filter down to real linkrevs
107 107 linkrevs = [l for l in linkrevs
108 108 if self.lrugetctx(l)[f].filenode() == node]
109 109 except Exception:
110 110 pass
111 111 self.warn(_(" (expected %s)") % " ".join
112 112 (map(pycompat.bytestr, linkrevs)))
113 113 lr = None # can't be trusted
114 114
115 115 try:
116 116 p1, p2 = obj.parents(node)
117 117 if p1 not in seen and p1 != nullid:
118 118 self.err(lr, _("unknown parent 1 %s of %s") %
119 119 (short(p1), short(node)), f)
120 120 if p2 not in seen and p2 != nullid:
121 121 self.err(lr, _("unknown parent 2 %s of %s") %
122 122 (short(p2), short(node)), f)
123 123 except Exception as inst:
124 124 self.exc(lr, _("checking parents of %s") % short(node), inst, f)
125 125
126 126 if node in seen:
127 127 self.err(lr, _("duplicate revision %d (%d)") % (i, seen[node]), f)
128 128 seen[node] = i
129 129 return lr
130 130
131 131 def verify(self):
132 132 repo = self.repo
133 133
134 134 ui = repo.ui
135 135
136 136 if not repo.url().startswith('file:'):
137 137 raise error.Abort(_("cannot verify bundle or remote repos"))
138 138
139 139 if os.path.exists(repo.sjoin("journal")):
140 140 ui.warn(_("abandoned transaction found - run hg recover\n"))
141 141
142 142 if ui.verbose or not self.revlogv1:
143 143 ui.status(_("repository uses revlog format %d\n") %
144 144 (self.revlogv1 and 1 or 0))
145 145
146 146 mflinkrevs, filelinkrevs = self._verifychangelog()
147 147
148 148 filenodes = self._verifymanifest(mflinkrevs)
149 149 del mflinkrevs
150 150
151 151 self._crosscheckfiles(filelinkrevs, filenodes)
152 152
153 153 totalfiles, filerevisions = self._verifyfiles(filenodes, filelinkrevs)
154 154
155 155 ui.status(_("%d files, %d changesets, %d total revisions\n") %
156 156 (totalfiles, len(repo.changelog), filerevisions))
157 157 if self.warnings:
158 158 ui.warn(_("%d warnings encountered!\n") % self.warnings)
159 159 if self.fncachewarned:
160 160 ui.warn(_('hint: run "hg debugrebuildfncache" to recover from '
161 161 'corrupt fncache\n'))
162 162 if self.errors:
163 163 ui.warn(_("%d integrity errors encountered!\n") % self.errors)
164 164 if self.badrevs:
165 165 ui.warn(_("(first damaged changeset appears to be %d)\n")
166 166 % min(self.badrevs))
167 167 return 1
168 168
169 169 def _verifychangelog(self):
170 170 ui = self.ui
171 171 repo = self.repo
172 172 match = self.match
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 match(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, dir="", storefiles=None,
201 201 progress=None):
202 202 repo = self.repo
203 203 ui = self.ui
204 204 match = self.match
205 205 mfl = self.repo.manifestlog
206 206 mf = mfl._revlog.dirlog(dir)
207 207
208 208 if not dir:
209 209 self.ui.status(_("checking manifests\n"))
210 210
211 211 filenodes = {}
212 212 subdirnodes = {}
213 213 seen = {}
214 214 label = "manifest"
215 215 if dir:
216 216 label = dir
217 217 revlogfiles = mf.files()
218 218 storefiles.difference_update(revlogfiles)
219 219 if progress: # should be true since we're in a subdirectory
220 220 progress()
221 221 if self.refersmf:
222 222 # Do not check manifest if there are only changelog entries with
223 223 # null manifests.
224 224 self.checklog(mf, label, 0)
225 225 total = len(mf)
226 226 for i in mf:
227 227 if not dir:
228 228 ui.progress(_('checking'), i, total=total, unit=_('manifests'))
229 229 n = mf.node(i)
230 230 lr = self.checkentry(mf, i, n, seen, mflinkrevs.get(n, []), label)
231 231 if n in mflinkrevs:
232 232 del mflinkrevs[n]
233 233 elif dir:
234 234 self.err(lr, _("%s not in parent-directory manifest") %
235 235 short(n), label)
236 236 else:
237 237 self.err(lr, _("%s not in changesets") % short(n), label)
238 238
239 239 try:
240 240 mfdelta = mfl.get(dir, n).readdelta(shallow=True)
241 241 for f, fn, fl in mfdelta.iterentries():
242 242 if not f:
243 243 self.err(lr, _("entry without name in manifest"))
244 244 elif f == "/dev/null": # ignore this in very old repos
245 245 continue
246 246 fullpath = dir + _normpath(f)
247 247 if fl == 't':
248 248 if not match.visitdir(fullpath):
249 249 continue
250 250 subdirnodes.setdefault(fullpath + '/', {}).setdefault(
251 251 fn, []).append(lr)
252 252 else:
253 253 if not match(fullpath):
254 254 continue
255 255 filenodes.setdefault(fullpath, {}).setdefault(fn, lr)
256 256 except Exception as inst:
257 257 self.exc(lr, _("reading delta %s") % short(n), inst, label)
258 258 if not dir:
259 259 ui.progress(_('checking'), None)
260 260
261 261 if self.havemf:
262 262 for c, m in sorted([(c, m) for m in mflinkrevs
263 263 for c in mflinkrevs[m]]):
264 264 if dir:
265 265 self.err(c, _("parent-directory manifest refers to unknown "
266 266 "revision %s") % short(m), label)
267 267 else:
268 268 self.err(c, _("changeset refers to unknown revision %s") %
269 269 short(m), label)
270 270
271 271 if not dir and subdirnodes:
272 272 self.ui.status(_("checking directory manifests\n"))
273 273 storefiles = set()
274 274 subdirs = set()
275 275 revlogv1 = self.revlogv1
276 276 for f, f2, size in repo.store.datafiles():
277 277 if not f:
278 278 self.err(None, _("cannot decode filename '%s'") % f2)
279 279 elif (size > 0 or not revlogv1) and f.startswith('meta/'):
280 280 storefiles.add(_normpath(f))
281 281 subdirs.add(os.path.dirname(f))
282 282 subdircount = len(subdirs)
283 283 currentsubdir = [0]
284 284 def progress():
285 285 currentsubdir[0] += 1
286 286 ui.progress(_('checking'), currentsubdir[0], total=subdircount,
287 287 unit=_('manifests'))
288 288
289 289 for subdir, linkrevs in subdirnodes.iteritems():
290 290 subdirfilenodes = self._verifymanifest(linkrevs, subdir, storefiles,
291 291 progress)
292 292 for f, onefilenodes in subdirfilenodes.iteritems():
293 293 filenodes.setdefault(f, {}).update(onefilenodes)
294 294
295 295 if not dir and subdirnodes:
296 296 ui.progress(_('checking'), None)
297 297 for f in sorted(storefiles):
298 self.warn(_("warning: orphan revlog '%s'") % f)
298 self.warn(_("warning: orphan data file '%s'") % f)
299 299
300 300 return filenodes
301 301
302 302 def _crosscheckfiles(self, filelinkrevs, filenodes):
303 303 repo = self.repo
304 304 ui = self.ui
305 305 ui.status(_("crosschecking files in changesets and manifests\n"))
306 306
307 307 total = len(filelinkrevs) + len(filenodes)
308 308 count = 0
309 309 if self.havemf:
310 310 for f in sorted(filelinkrevs):
311 311 count += 1
312 312 ui.progress(_('crosschecking'), count, total=total)
313 313 if f not in filenodes:
314 314 lr = filelinkrevs[f][0]
315 315 self.err(lr, _("in changeset but not in manifest"), f)
316 316
317 317 if self.havecl:
318 318 for f in sorted(filenodes):
319 319 count += 1
320 320 ui.progress(_('crosschecking'), count, total=total)
321 321 if f not in filelinkrevs:
322 322 try:
323 323 fl = repo.file(f)
324 324 lr = min([fl.linkrev(fl.rev(n)) for n in filenodes[f]])
325 325 except Exception:
326 326 lr = None
327 327 self.err(lr, _("in manifest but not in changeset"), f)
328 328
329 329 ui.progress(_('crosschecking'), None)
330 330
331 331 def _verifyfiles(self, filenodes, filelinkrevs):
332 332 repo = self.repo
333 333 ui = self.ui
334 334 lrugetctx = self.lrugetctx
335 335 revlogv1 = self.revlogv1
336 336 havemf = self.havemf
337 337 ui.status(_("checking files\n"))
338 338
339 339 storefiles = set()
340 340 for f, f2, size in repo.store.datafiles():
341 341 if not f:
342 342 self.err(None, _("cannot decode filename '%s'") % f2)
343 343 elif (size > 0 or not revlogv1) and f.startswith('data/'):
344 344 storefiles.add(_normpath(f))
345 345
346 346 files = sorted(set(filenodes) | set(filelinkrevs))
347 347 total = len(files)
348 348 revisions = 0
349 349 for i, f in enumerate(files):
350 350 ui.progress(_('checking'), i, item=f, total=total, unit=_('files'))
351 351 try:
352 352 linkrevs = filelinkrevs[f]
353 353 except KeyError:
354 354 # in manifest but not in changelog
355 355 linkrevs = []
356 356
357 357 if linkrevs:
358 358 lr = linkrevs[0]
359 359 else:
360 360 lr = None
361 361
362 362 try:
363 363 fl = repo.file(f)
364 364 except error.RevlogError as e:
365 365 self.err(lr, _("broken revlog! (%s)") % e, f)
366 366 continue
367 367
368 368 for ff in fl.files():
369 369 try:
370 370 storefiles.remove(ff)
371 371 except KeyError:
372 372 self.warn(_(" warning: revlog '%s' not in fncache!") % ff)
373 373 self.fncachewarned = True
374 374
375 375 self.checklog(fl, f, lr)
376 376 seen = {}
377 377 rp = None
378 378 for i in fl:
379 379 revisions += 1
380 380 n = fl.node(i)
381 381 lr = self.checkentry(fl, i, n, seen, linkrevs, f)
382 382 if f in filenodes:
383 383 if havemf and n not in filenodes[f]:
384 384 self.err(lr, _("%s not in manifests") % (short(n)), f)
385 385 else:
386 386 del filenodes[f][n]
387 387
388 388 # Verify contents. 4 cases to care about:
389 389 #
390 390 # common: the most common case
391 391 # rename: with a rename
392 392 # meta: file content starts with b'\1\n', the metadata
393 393 # header defined in filelog.py, but without a rename
394 394 # ext: content stored externally
395 395 #
396 396 # More formally, their differences are shown below:
397 397 #
398 398 # | common | rename | meta | ext
399 399 # -------------------------------------------------------
400 400 # flags() | 0 | 0 | 0 | not 0
401 401 # renamed() | False | True | False | ?
402 402 # rawtext[0:2]=='\1\n'| False | True | True | ?
403 403 #
404 404 # "rawtext" means the raw text stored in revlog data, which
405 405 # could be retrieved by "revision(rev, raw=True)". "text"
406 406 # mentioned below is "revision(rev, raw=False)".
407 407 #
408 408 # There are 3 different lengths stored physically:
409 409 # 1. L1: rawsize, stored in revlog index
410 410 # 2. L2: len(rawtext), stored in revlog data
411 411 # 3. L3: len(text), stored in revlog data if flags==0, or
412 412 # possibly somewhere else if flags!=0
413 413 #
414 414 # L1 should be equal to L2. L3 could be different from them.
415 415 # "text" may or may not affect commit hash depending on flag
416 416 # processors (see revlog.addflagprocessor).
417 417 #
418 418 # | common | rename | meta | ext
419 419 # -------------------------------------------------
420 420 # rawsize() | L1 | L1 | L1 | L1
421 421 # size() | L1 | L2-LM | L1(*) | L1 (?)
422 422 # len(rawtext) | L2 | L2 | L2 | L2
423 423 # len(text) | L2 | L2 | L2 | L3
424 424 # len(read()) | L2 | L2-LM | L2-LM | L3 (?)
425 425 #
426 426 # LM: length of metadata, depending on rawtext
427 427 # (*): not ideal, see comment in filelog.size
428 428 # (?): could be "- len(meta)" if the resolved content has
429 429 # rename metadata
430 430 #
431 431 # Checks needed to be done:
432 432 # 1. length check: L1 == L2, in all cases.
433 433 # 2. hash check: depending on flag processor, we may need to
434 434 # use either "text" (external), or "rawtext" (in revlog).
435 435 try:
436 436 skipflags = self.skipflags
437 437 if skipflags:
438 438 skipflags &= fl.flags(i)
439 439 if not skipflags:
440 440 fl.read(n) # side effect: read content and do checkhash
441 441 rp = fl.renamed(n)
442 442 # the "L1 == L2" check
443 443 l1 = fl.rawsize(i)
444 444 l2 = len(fl.revision(n, raw=True))
445 445 if l1 != l2:
446 446 self.err(lr, _("unpacked size is %s, %s expected") %
447 447 (l2, l1), f)
448 448 except error.CensoredNodeError:
449 449 # experimental config: censor.policy
450 450 if ui.config("censor", "policy") == "abort":
451 451 self.err(lr, _("censored file data"), f)
452 452 except Exception as inst:
453 453 self.exc(lr, _("unpacking %s") % short(n), inst, f)
454 454
455 455 # check renames
456 456 try:
457 457 if rp:
458 458 if lr is not None and ui.verbose:
459 459 ctx = lrugetctx(lr)
460 460 if not any(rp[0] in pctx for pctx in ctx.parents()):
461 461 self.warn(_("warning: copy source of '%s' not"
462 462 " in parents of %s") % (f, ctx))
463 463 fl2 = repo.file(rp[0])
464 464 if not len(fl2):
465 465 self.err(lr, _("empty or missing copy source "
466 466 "revlog %s:%s") % (rp[0], short(rp[1])), f)
467 467 elif rp[1] == nullid:
468 468 ui.note(_("warning: %s@%s: copy source"
469 469 " revision is nullid %s:%s\n")
470 470 % (f, lr, rp[0], short(rp[1])))
471 471 else:
472 472 fl2.rev(rp[1])
473 473 except Exception as inst:
474 474 self.exc(lr, _("checking rename of %s") % short(n), inst, f)
475 475
476 476 # cross-check
477 477 if f in filenodes:
478 478 fns = [(v, k) for k, v in filenodes[f].iteritems()]
479 479 for lr, node in sorted(fns):
480 480 self.err(lr, _("manifest refers to unknown revision %s") %
481 481 short(node), f)
482 482 ui.progress(_('checking'), None)
483 483
484 484 for f in sorted(storefiles):
485 self.warn(_("warning: orphan revlog '%s'") % f)
485 self.warn(_("warning: orphan data file '%s'") % f)
486 486
487 487 return len(files), revisions
@@ -1,139 +1,139 b''
1 1 #require unix-permissions no-root
2 2
3 3 $ cat > $TESTTMP/dumpjournal.py <<EOF
4 4 > import sys
5 5 > for entry in sys.stdin.read().split('\n'):
6 6 > if entry:
7 7 > print(entry.split('\x00')[0])
8 8 > EOF
9 9
10 10 $ echo "[extensions]" >> $HGRCPATH
11 11 $ echo "mq=">> $HGRCPATH
12 12
13 13 $ teststrip() {
14 14 > hg -q up -C $1
15 15 > echo % before update $1, strip $2
16 16 > hg parents
17 17 > chmod -$3 $4
18 18 > hg strip $2 2>&1 | sed 's/\(bundle\).*/\1/' | sed 's/Permission denied.*\.hg\/store\/\(.*\)/Permission denied \.hg\/store\/\1/'
19 19 > echo % after update $1, strip $2
20 20 > chmod +$3 $4
21 21 > hg verify
22 22 > echo % journal contents
23 23 > if [ -f .hg/store/journal ]; then
24 24 > cat .hg/store/journal | $PYTHON $TESTTMP/dumpjournal.py
25 25 > else
26 26 > echo "(no journal)"
27 27 > fi
28 28 > ls .hg/store/journal >/dev/null 2>&1 && hg recover
29 29 > ls .hg/strip-backup/* >/dev/null 2>&1 && hg unbundle -q .hg/strip-backup/*
30 30 > rm -rf .hg/strip-backup
31 31 > }
32 32
33 33 $ hg init test
34 34 $ cd test
35 35 $ echo a > a
36 36 $ hg -q ci -m "a" -A
37 37 $ echo b > b
38 38 $ hg -q ci -m "b" -A
39 39 $ echo b2 >> b
40 40 $ hg -q ci -m "b2" -A
41 41 $ echo c > c
42 42 $ hg -q ci -m "c" -A
43 43 $ teststrip 0 2 w .hg/store/data/b.i
44 44 % before update 0, strip 2
45 45 changeset: 0:cb9a9f314b8b
46 46 user: test
47 47 date: Thu Jan 01 00:00:00 1970 +0000
48 48 summary: a
49 49
50 50 saved backup bundle
51 51 transaction abort!
52 52 failed to truncate data/b.i
53 53 rollback failed - please run hg recover
54 54 strip failed, backup bundle
55 55 abort: Permission denied .hg/store/data/b.i
56 56 % after update 0, strip 2
57 57 abandoned transaction found - run hg recover
58 58 checking changesets
59 59 checking manifests
60 60 crosschecking files in changesets and manifests
61 61 checking files
62 62 b@?: rev 1 points to nonexistent changeset 2
63 63 (expected 1)
64 64 b@?: 736c29771fba not in manifests
65 warning: orphan revlog 'data/c.i'
65 warning: orphan data file 'data/c.i'
66 66 2 files, 2 changesets, 3 total revisions
67 67 2 warnings encountered!
68 68 2 integrity errors encountered!
69 69 % journal contents
70 70 00changelog.i
71 71 00manifest.i
72 72 data/b.i
73 73 data/c.i
74 74 rolling back interrupted transaction
75 75 checking changesets
76 76 checking manifests
77 77 crosschecking files in changesets and manifests
78 78 checking files
79 79 2 files, 2 changesets, 2 total revisions
80 80 $ teststrip 0 2 r .hg/store/data/b.i
81 81 % before update 0, strip 2
82 82 changeset: 0:cb9a9f314b8b
83 83 user: test
84 84 date: Thu Jan 01 00:00:00 1970 +0000
85 85 summary: a
86 86
87 87 abort: Permission denied .hg/store/data/b.i
88 88 % after update 0, strip 2
89 89 checking changesets
90 90 checking manifests
91 91 crosschecking files in changesets and manifests
92 92 checking files
93 93 3 files, 4 changesets, 4 total revisions
94 94 % journal contents
95 95 (no journal)
96 96 $ teststrip 0 2 w .hg/store/00manifest.i
97 97 % before update 0, strip 2
98 98 changeset: 0:cb9a9f314b8b
99 99 user: test
100 100 date: Thu Jan 01 00:00:00 1970 +0000
101 101 summary: a
102 102
103 103 saved backup bundle
104 104 transaction abort!
105 105 failed to truncate 00manifest.i
106 106 rollback failed - please run hg recover
107 107 strip failed, backup bundle
108 108 abort: Permission denied .hg/store/00manifest.i
109 109 % after update 0, strip 2
110 110 abandoned transaction found - run hg recover
111 111 checking changesets
112 112 checking manifests
113 113 manifest@?: rev 2 points to nonexistent changeset 2
114 114 manifest@?: 3362547cdf64 not in changesets
115 115 manifest@?: rev 3 points to nonexistent changeset 3
116 116 manifest@?: 265a85892ecb not in changesets
117 117 crosschecking files in changesets and manifests
118 118 c@3: in manifest but not in changeset
119 119 checking files
120 120 b@?: rev 1 points to nonexistent changeset 2
121 121 (expected 1)
122 122 c@?: rev 0 points to nonexistent changeset 3
123 123 3 files, 2 changesets, 4 total revisions
124 124 1 warnings encountered!
125 125 7 integrity errors encountered!
126 126 (first damaged changeset appears to be 3)
127 127 % journal contents
128 128 00changelog.i
129 129 00manifest.i
130 130 data/b.i
131 131 data/c.i
132 132 rolling back interrupted transaction
133 133 checking changesets
134 134 checking manifests
135 135 crosschecking files in changesets and manifests
136 136 checking files
137 137 2 files, 2 changesets, 2 total revisions
138 138
139 139 $ cd ..
@@ -1,876 +1,876 b''
1 1 #require killdaemons
2 2
3 3 $ cat << EOF >> $HGRCPATH
4 4 > [ui]
5 5 > ssh=$PYTHON "$TESTDIR/dummyssh"
6 6 > EOF
7 7
8 8 Set up repo
9 9
10 10 $ hg --config experimental.treemanifest=True init repo
11 11 $ cd repo
12 12
13 13 Requirements get set on init
14 14
15 15 $ grep treemanifest .hg/requires
16 16 treemanifest
17 17
18 18 Without directories, looks like any other repo
19 19
20 20 $ echo 0 > a
21 21 $ echo 0 > b
22 22 $ hg ci -Aqm initial
23 23 $ hg debugdata -m 0
24 24 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
25 25 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
26 26
27 27 Submanifest is stored in separate revlog
28 28
29 29 $ mkdir dir1
30 30 $ echo 1 > dir1/a
31 31 $ echo 1 > dir1/b
32 32 $ echo 1 > e
33 33 $ hg ci -Aqm 'add dir1'
34 34 $ hg debugdata -m 1
35 35 a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
36 36 b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc)
37 37 dir1\x008b3ffd73f901e83304c83d33132c8e774ceac44et (esc)
38 38 e\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
39 39 $ hg debugdata --dir dir1 0
40 40 a\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
41 41 b\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
42 42
43 43 Can add nested directories
44 44
45 45 $ mkdir dir1/dir1
46 46 $ echo 2 > dir1/dir1/a
47 47 $ echo 2 > dir1/dir1/b
48 48 $ mkdir dir1/dir2
49 49 $ echo 2 > dir1/dir2/a
50 50 $ echo 2 > dir1/dir2/b
51 51 $ hg ci -Aqm 'add dir1/dir1'
52 52 $ hg files -r .
53 53 a
54 54 b
55 55 dir1/a
56 56 dir1/b
57 57 dir1/dir1/a
58 58 dir1/dir1/b
59 59 dir1/dir2/a
60 60 dir1/dir2/b
61 61 e
62 62
63 63 The manifest command works
64 64
65 65 $ hg manifest
66 66 a
67 67 b
68 68 dir1/a
69 69 dir1/b
70 70 dir1/dir1/a
71 71 dir1/dir1/b
72 72 dir1/dir2/a
73 73 dir1/dir2/b
74 74 e
75 75
76 76 Revision is not created for unchanged directory
77 77
78 78 $ mkdir dir2
79 79 $ echo 3 > dir2/a
80 80 $ hg add dir2
81 81 adding dir2/a
82 82 $ hg debugindex --dir dir1 > before
83 83 $ hg ci -qm 'add dir2'
84 84 $ hg debugindex --dir dir1 > after
85 85 $ diff before after
86 86 $ rm before after
87 87
88 88 Removing directory does not create an revlog entry
89 89
90 90 $ hg rm dir1/dir1
91 91 removing dir1/dir1/a
92 92 removing dir1/dir1/b
93 93 $ hg debugindex --dir dir1/dir1 > before
94 94 $ hg ci -qm 'remove dir1/dir1'
95 95 $ hg debugindex --dir dir1/dir1 > after
96 96 $ diff before after
97 97 $ rm before after
98 98
99 99 Check that hg files (calls treemanifest.walk()) works
100 100 without loading all directory revlogs
101 101
102 102 $ hg co 'desc("add dir2")'
103 103 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
104 104 $ mv .hg/store/meta/dir2 .hg/store/meta/dir2-backup
105 105 $ hg files -r . dir1
106 106 dir1/a
107 107 dir1/b
108 108 dir1/dir1/a
109 109 dir1/dir1/b
110 110 dir1/dir2/a
111 111 dir1/dir2/b
112 112
113 113 Check that status between revisions works (calls treemanifest.matches())
114 114 without loading all directory revlogs
115 115
116 116 $ hg status --rev 'desc("add dir1")' --rev . dir1
117 117 A dir1/dir1/a
118 118 A dir1/dir1/b
119 119 A dir1/dir2/a
120 120 A dir1/dir2/b
121 121 $ mv .hg/store/meta/dir2-backup .hg/store/meta/dir2
122 122
123 123 Merge creates 2-parent revision of directory revlog
124 124
125 125 $ echo 5 > dir1/a
126 126 $ hg ci -Aqm 'modify dir1/a'
127 127 $ hg co '.^'
128 128 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
129 129 $ echo 6 > dir1/b
130 130 $ hg ci -Aqm 'modify dir1/b'
131 131 $ hg merge 'desc("modify dir1/a")'
132 132 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
133 133 (branch merge, don't forget to commit)
134 134 $ hg ci -m 'conflict-free merge involving dir1/'
135 135 $ cat dir1/a
136 136 5
137 137 $ cat dir1/b
138 138 6
139 139 $ hg debugindex --dir dir1
140 140 rev linkrev nodeid p1 p2
141 141 0 1 8b3ffd73f901 000000000000 000000000000
142 142 1 2 68e9d057c5a8 8b3ffd73f901 000000000000
143 143 2 4 4698198d2624 68e9d057c5a8 000000000000
144 144 3 5 44844058ccce 68e9d057c5a8 000000000000
145 145 4 6 bf3d9b744927 68e9d057c5a8 000000000000
146 146 5 7 dde7c0af2a03 bf3d9b744927 44844058ccce
147 147
148 148 Merge keeping directory from parent 1 does not create revlog entry. (Note that
149 149 dir1's manifest does change, but only because dir1/a's filelog changes.)
150 150
151 151 $ hg co 'desc("add dir2")'
152 152 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
153 153 $ echo 8 > dir2/a
154 154 $ hg ci -m 'modify dir2/a'
155 155 created new head
156 156
157 157 $ hg debugindex --dir dir2 > before
158 158 $ hg merge 'desc("modify dir1/a")'
159 159 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 160 (branch merge, don't forget to commit)
161 161 $ hg revert -r 'desc("modify dir2/a")' .
162 162 reverting dir1/a
163 163 $ hg ci -m 'merge, keeping parent 1'
164 164 $ hg debugindex --dir dir2 > after
165 165 $ diff before after
166 166 $ rm before after
167 167
168 168 Merge keeping directory from parent 2 does not create revlog entry. (Note that
169 169 dir2's manifest does change, but only because dir2/a's filelog changes.)
170 170
171 171 $ hg co 'desc("modify dir2/a")'
172 172 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
173 173 $ hg debugindex --dir dir1 > before
174 174 $ hg merge 'desc("modify dir1/a")'
175 175 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
176 176 (branch merge, don't forget to commit)
177 177 $ hg revert -r 'desc("modify dir1/a")' .
178 178 reverting dir2/a
179 179 $ hg ci -m 'merge, keeping parent 2'
180 180 created new head
181 181 $ hg debugindex --dir dir1 > after
182 182 $ diff before after
183 183 $ rm before after
184 184
185 185 Create flat source repo for tests with mixed flat/tree manifests
186 186
187 187 $ cd ..
188 188 $ hg init repo-flat
189 189 $ cd repo-flat
190 190
191 191 Create a few commits with flat manifest
192 192
193 193 $ echo 0 > a
194 194 $ echo 0 > b
195 195 $ echo 0 > e
196 196 $ for d in dir1 dir1/dir1 dir1/dir2 dir2
197 197 > do
198 198 > mkdir $d
199 199 > echo 0 > $d/a
200 200 > echo 0 > $d/b
201 201 > done
202 202 $ hg ci -Aqm initial
203 203
204 204 $ echo 1 > a
205 205 $ echo 1 > dir1/a
206 206 $ echo 1 > dir1/dir1/a
207 207 $ hg ci -Aqm 'modify on branch 1'
208 208
209 209 $ hg co 0
210 210 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
211 211 $ echo 2 > b
212 212 $ echo 2 > dir1/b
213 213 $ echo 2 > dir1/dir1/b
214 214 $ hg ci -Aqm 'modify on branch 2'
215 215
216 216 $ hg merge 1
217 217 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
218 218 (branch merge, don't forget to commit)
219 219 $ hg ci -m 'merge of flat manifests to new flat manifest'
220 220
221 221 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
222 222 $ cat hg.pid >> $DAEMON_PIDS
223 223
224 224 Create clone with tree manifests enabled
225 225
226 226 $ cd ..
227 227 $ hg clone --config experimental.treemanifest=1 \
228 228 > http://localhost:$HGPORT repo-mixed -r 1
229 229 adding changesets
230 230 adding manifests
231 231 adding file changes
232 232 added 2 changesets with 14 changes to 11 files
233 233 new changesets 5b02a3e8db7e:581ef6037d8b
234 234 updating to branch default
235 235 11 files updated, 0 files merged, 0 files removed, 0 files unresolved
236 236 $ cd repo-mixed
237 237 $ test -d .hg/store/meta
238 238 [1]
239 239 $ grep treemanifest .hg/requires
240 240 treemanifest
241 241
242 242 Should be possible to push updates from flat to tree manifest repo
243 243
244 244 $ hg -R ../repo-flat push ssh://user@dummy/repo-mixed
245 245 pushing to ssh://user@dummy/repo-mixed
246 246 searching for changes
247 247 remote: adding changesets
248 248 remote: adding manifests
249 249 remote: adding file changes
250 250 remote: added 2 changesets with 3 changes to 3 files
251 251
252 252 Commit should store revlog per directory
253 253
254 254 $ hg co 1
255 255 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 256 $ echo 3 > a
257 257 $ echo 3 > dir1/a
258 258 $ echo 3 > dir1/dir1/a
259 259 $ hg ci -m 'first tree'
260 260 created new head
261 261 $ find .hg/store/meta | sort
262 262 .hg/store/meta
263 263 .hg/store/meta/dir1
264 264 .hg/store/meta/dir1/00manifest.i
265 265 .hg/store/meta/dir1/dir1
266 266 .hg/store/meta/dir1/dir1/00manifest.i
267 267 .hg/store/meta/dir1/dir2
268 268 .hg/store/meta/dir1/dir2/00manifest.i
269 269 .hg/store/meta/dir2
270 270 .hg/store/meta/dir2/00manifest.i
271 271
272 272 Merge of two trees
273 273
274 274 $ hg co 2
275 275 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 276 $ hg merge 1
277 277 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
278 278 (branch merge, don't forget to commit)
279 279 $ hg ci -m 'merge of flat manifests to new tree manifest'
280 280 created new head
281 281 $ hg diff -r 3
282 282
283 283 Parent of tree root manifest should be flat manifest, and two for merge
284 284
285 285 $ hg debugindex -m
286 286 rev linkrev nodeid p1 p2
287 287 0 0 40536115ed9e 000000000000 000000000000
288 288 1 1 f3376063c255 40536115ed9e 000000000000
289 289 2 2 5d9b9da231a2 40536115ed9e 000000000000
290 290 3 3 d17d663cbd8a 5d9b9da231a2 f3376063c255
291 291 4 4 51e32a8c60ee f3376063c255 000000000000
292 292 5 5 cc5baa78b230 5d9b9da231a2 f3376063c255
293 293
294 294
295 295 Status across flat/tree boundary should work
296 296
297 297 $ hg status --rev '.^' --rev .
298 298 M a
299 299 M dir1/a
300 300 M dir1/dir1/a
301 301
302 302
303 303 Turning off treemanifest config has no effect
304 304
305 305 $ hg debugindex --dir dir1
306 306 rev linkrev nodeid p1 p2
307 307 0 4 064927a0648a 000000000000 000000000000
308 308 1 5 25ecb8cb8618 000000000000 000000000000
309 309 $ echo 2 > dir1/a
310 310 $ hg --config experimental.treemanifest=False ci -qm 'modify dir1/a'
311 311 $ hg debugindex --dir dir1
312 312 rev linkrev nodeid p1 p2
313 313 0 4 064927a0648a 000000000000 000000000000
314 314 1 5 25ecb8cb8618 000000000000 000000000000
315 315 2 6 5b16163a30c6 25ecb8cb8618 000000000000
316 316
317 317 Stripping and recovering changes should work
318 318
319 319 $ hg st --change tip
320 320 M dir1/a
321 321 $ hg --config extensions.strip= strip tip
322 322 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
323 323 saved backup bundle to $TESTTMP/repo-mixed/.hg/strip-backup/51cfd7b1e13b-78a2f3ed-backup.hg
324 324 $ hg debugindex --dir dir1
325 325 rev linkrev nodeid p1 p2
326 326 0 4 064927a0648a 000000000000 000000000000
327 327 1 5 25ecb8cb8618 000000000000 000000000000
328 328
329 329 #if repobundlerepo
330 330 $ hg incoming .hg/strip-backup/*
331 331 comparing with .hg/strip-backup/*-backup.hg (glob)
332 332 searching for changes
333 333 changeset: 6:51cfd7b1e13b
334 334 tag: tip
335 335 user: test
336 336 date: Thu Jan 01 00:00:00 1970 +0000
337 337 summary: modify dir1/a
338 338
339 339 #endif
340 340
341 341 $ hg unbundle .hg/strip-backup/*
342 342 adding changesets
343 343 adding manifests
344 344 adding file changes
345 345 added 1 changesets with 1 changes to 1 files
346 346 new changesets 51cfd7b1e13b
347 347 (run 'hg update' to get a working copy)
348 348 $ hg --config extensions.strip= strip tip
349 349 saved backup bundle to $TESTTMP/repo-mixed/.hg/strip-backup/*-backup.hg (glob)
350 350 $ hg unbundle -q .hg/strip-backup/*
351 351 $ hg debugindex --dir dir1
352 352 rev linkrev nodeid p1 p2
353 353 0 4 064927a0648a 000000000000 000000000000
354 354 1 5 25ecb8cb8618 000000000000 000000000000
355 355 2 6 5b16163a30c6 25ecb8cb8618 000000000000
356 356 $ hg st --change tip
357 357 M dir1/a
358 358
359 359 Shelving and unshelving should work
360 360
361 361 $ echo foo >> dir1/a
362 362 $ hg --config extensions.shelve= shelve
363 363 shelved as default
364 364 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
365 365 $ hg --config extensions.shelve= unshelve
366 366 unshelving change 'default'
367 367 $ hg diff --nodates
368 368 diff -r 708a273da119 dir1/a
369 369 --- a/dir1/a
370 370 +++ b/dir1/a
371 371 @@ -1,1 +1,2 @@
372 372 1
373 373 +foo
374 374
375 375 Pushing from treemanifest repo to an empty repo makes that a treemanifest repo
376 376
377 377 $ cd ..
378 378 $ hg init empty-repo
379 379 $ cat << EOF >> empty-repo/.hg/hgrc
380 380 > [experimental]
381 381 > changegroup3=yes
382 382 > EOF
383 383 $ grep treemanifest empty-repo/.hg/requires
384 384 [1]
385 385 $ hg push -R repo -r 0 empty-repo
386 386 pushing to empty-repo
387 387 searching for changes
388 388 adding changesets
389 389 adding manifests
390 390 adding file changes
391 391 added 1 changesets with 2 changes to 2 files
392 392 $ grep treemanifest empty-repo/.hg/requires
393 393 treemanifest
394 394
395 395 Pushing to an empty repo works
396 396
397 397 $ hg --config experimental.treemanifest=1 init clone
398 398 $ grep treemanifest clone/.hg/requires
399 399 treemanifest
400 400 $ hg push -R repo clone
401 401 pushing to clone
402 402 searching for changes
403 403 adding changesets
404 404 adding manifests
405 405 adding file changes
406 406 added 11 changesets with 15 changes to 10 files (+3 heads)
407 407 $ grep treemanifest clone/.hg/requires
408 408 treemanifest
409 409 $ hg -R clone verify
410 410 checking changesets
411 411 checking manifests
412 412 checking directory manifests
413 413 crosschecking files in changesets and manifests
414 414 checking files
415 415 10 files, 11 changesets, 15 total revisions
416 416
417 417 Create deeper repo with tree manifests.
418 418
419 419 $ hg --config experimental.treemanifest=True init deeprepo
420 420 $ cd deeprepo
421 421
422 422 $ mkdir .A
423 423 $ mkdir b
424 424 $ mkdir b/bar
425 425 $ mkdir b/bar/orange
426 426 $ mkdir b/bar/orange/fly
427 427 $ mkdir b/foo
428 428 $ mkdir b/foo/apple
429 429 $ mkdir b/foo/apple/bees
430 430
431 431 $ touch .A/one.txt
432 432 $ touch .A/two.txt
433 433 $ touch b/bar/fruits.txt
434 434 $ touch b/bar/orange/fly/gnat.py
435 435 $ touch b/bar/orange/fly/housefly.txt
436 436 $ touch b/foo/apple/bees/flower.py
437 437 $ touch c.txt
438 438 $ touch d.py
439 439
440 440 $ hg ci -Aqm 'initial'
441 441
442 442 $ echo >> .A/one.txt
443 443 $ echo >> .A/two.txt
444 444 $ echo >> b/bar/fruits.txt
445 445 $ echo >> b/bar/orange/fly/gnat.py
446 446 $ echo >> b/bar/orange/fly/housefly.txt
447 447 $ echo >> b/foo/apple/bees/flower.py
448 448 $ echo >> c.txt
449 449 $ echo >> d.py
450 450 $ hg ci -Aqm 'second'
451 451
452 452 We'll see that visitdir works by removing some treemanifest revlogs and running
453 453 the files command with various parameters.
454 454
455 455 Test files from the root.
456 456
457 457 $ hg files -r .
458 458 .A/one.txt
459 459 .A/two.txt
460 460 b/bar/fruits.txt
461 461 b/bar/orange/fly/gnat.py
462 462 b/bar/orange/fly/housefly.txt
463 463 b/foo/apple/bees/flower.py
464 464 c.txt
465 465 d.py
466 466
467 467 Excludes with a glob should not exclude everything from the glob's root
468 468
469 469 $ hg files -r . -X 'b/fo?' b
470 470 b/bar/fruits.txt
471 471 b/bar/orange/fly/gnat.py
472 472 b/bar/orange/fly/housefly.txt
473 473 $ cp -R .hg/store .hg/store-copy
474 474
475 475 Test files for a subdirectory.
476 476
477 477 $ rm -r .hg/store/meta/~2e_a
478 478 $ hg files -r . b
479 479 b/bar/fruits.txt
480 480 b/bar/orange/fly/gnat.py
481 481 b/bar/orange/fly/housefly.txt
482 482 b/foo/apple/bees/flower.py
483 483 $ hg diff -r '.^' -r . --stat b
484 484 b/bar/fruits.txt | 1 +
485 485 b/bar/orange/fly/gnat.py | 1 +
486 486 b/bar/orange/fly/housefly.txt | 1 +
487 487 b/foo/apple/bees/flower.py | 1 +
488 488 4 files changed, 4 insertions(+), 0 deletions(-)
489 489 $ cp -R .hg/store-copy/. .hg/store
490 490
491 491 Test files with just includes and excludes.
492 492
493 493 $ rm -r .hg/store/meta/~2e_a
494 494 $ rm -r .hg/store/meta/b/bar/orange/fly
495 495 $ rm -r .hg/store/meta/b/foo/apple/bees
496 496 $ hg files -r . -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
497 497 b/bar/fruits.txt
498 498 $ hg diff -r '.^' -r . --stat -I path:b/bar -X path:b/bar/orange/fly -I path:b/foo -X path:b/foo/apple/bees
499 499 b/bar/fruits.txt | 1 +
500 500 1 files changed, 1 insertions(+), 0 deletions(-)
501 501 $ cp -R .hg/store-copy/. .hg/store
502 502
503 503 Test files for a subdirectory, excluding a directory within it.
504 504
505 505 $ rm -r .hg/store/meta/~2e_a
506 506 $ rm -r .hg/store/meta/b/foo
507 507 $ hg files -r . -X path:b/foo b
508 508 b/bar/fruits.txt
509 509 b/bar/orange/fly/gnat.py
510 510 b/bar/orange/fly/housefly.txt
511 511 $ hg diff -r '.^' -r . --stat -X path:b/foo b
512 512 b/bar/fruits.txt | 1 +
513 513 b/bar/orange/fly/gnat.py | 1 +
514 514 b/bar/orange/fly/housefly.txt | 1 +
515 515 3 files changed, 3 insertions(+), 0 deletions(-)
516 516 $ cp -R .hg/store-copy/. .hg/store
517 517
518 518 Test files for a sub directory, including only a directory within it, and
519 519 including an unrelated directory.
520 520
521 521 $ rm -r .hg/store/meta/~2e_a
522 522 $ rm -r .hg/store/meta/b/foo
523 523 $ hg files -r . -I path:b/bar/orange -I path:a b
524 524 b/bar/orange/fly/gnat.py
525 525 b/bar/orange/fly/housefly.txt
526 526 $ hg diff -r '.^' -r . --stat -I path:b/bar/orange -I path:a b
527 527 b/bar/orange/fly/gnat.py | 1 +
528 528 b/bar/orange/fly/housefly.txt | 1 +
529 529 2 files changed, 2 insertions(+), 0 deletions(-)
530 530 $ cp -R .hg/store-copy/. .hg/store
531 531
532 532 Test files for a pattern, including a directory, and excluding a directory
533 533 within that.
534 534
535 535 $ rm -r .hg/store/meta/~2e_a
536 536 $ rm -r .hg/store/meta/b/foo
537 537 $ rm -r .hg/store/meta/b/bar/orange
538 538 $ hg files -r . glob:**.txt -I path:b/bar -X path:b/bar/orange
539 539 b/bar/fruits.txt
540 540 $ hg diff -r '.^' -r . --stat glob:**.txt -I path:b/bar -X path:b/bar/orange
541 541 b/bar/fruits.txt | 1 +
542 542 1 files changed, 1 insertions(+), 0 deletions(-)
543 543 $ cp -R .hg/store-copy/. .hg/store
544 544
545 545 Add some more changes to the deep repo
546 546 $ echo narf >> b/bar/fruits.txt
547 547 $ hg ci -m narf
548 548 $ echo troz >> b/bar/orange/fly/gnat.py
549 549 $ hg ci -m troz
550 550
551 551 Verify works
552 552 $ hg verify
553 553 checking changesets
554 554 checking manifests
555 555 checking directory manifests
556 556 crosschecking files in changesets and manifests
557 557 checking files
558 558 8 files, 4 changesets, 18 total revisions
559 559
560 560 Dirlogs are included in fncache
561 561 $ grep meta/.A/00manifest.i .hg/store/fncache
562 562 meta/.A/00manifest.i
563 563
564 564 Rebuilt fncache includes dirlogs
565 565 $ rm .hg/store/fncache
566 566 $ hg debugrebuildfncache
567 567 adding data/.A/one.txt.i
568 568 adding data/.A/two.txt.i
569 569 adding data/b/bar/fruits.txt.i
570 570 adding data/b/bar/orange/fly/gnat.py.i
571 571 adding data/b/bar/orange/fly/housefly.txt.i
572 572 adding data/b/foo/apple/bees/flower.py.i
573 573 adding data/c.txt.i
574 574 adding data/d.py.i
575 575 adding meta/.A/00manifest.i
576 576 adding meta/b/00manifest.i
577 577 adding meta/b/bar/00manifest.i
578 578 adding meta/b/bar/orange/00manifest.i
579 579 adding meta/b/bar/orange/fly/00manifest.i
580 580 adding meta/b/foo/00manifest.i
581 581 adding meta/b/foo/apple/00manifest.i
582 582 adding meta/b/foo/apple/bees/00manifest.i
583 583 16 items added, 0 removed from fncache
584 584
585 585 Finish first server
586 586 $ killdaemons.py
587 587
588 588 Back up the recently added revlogs
589 589 $ cp -R .hg/store .hg/store-newcopy
590 590
591 591 Verify reports missing dirlog
592 592 $ rm .hg/store/meta/b/00manifest.*
593 593 $ hg verify
594 594 checking changesets
595 595 checking manifests
596 596 checking directory manifests
597 597 0: empty or missing b/
598 598 b/@0: parent-directory manifest refers to unknown revision 67688a370455
599 599 b/@1: parent-directory manifest refers to unknown revision f065da70369e
600 600 b/@2: parent-directory manifest refers to unknown revision ac0d30948e0b
601 601 b/@3: parent-directory manifest refers to unknown revision 367152e6af28
602 warning: orphan revlog 'meta/b/bar/00manifest.i'
603 warning: orphan revlog 'meta/b/bar/orange/00manifest.i'
604 warning: orphan revlog 'meta/b/bar/orange/fly/00manifest.i'
605 warning: orphan revlog 'meta/b/foo/00manifest.i'
606 warning: orphan revlog 'meta/b/foo/apple/00manifest.i'
607 warning: orphan revlog 'meta/b/foo/apple/bees/00manifest.i'
602 warning: orphan data file 'meta/b/bar/00manifest.i'
603 warning: orphan data file 'meta/b/bar/orange/00manifest.i'
604 warning: orphan data file 'meta/b/bar/orange/fly/00manifest.i'
605 warning: orphan data file 'meta/b/foo/00manifest.i'
606 warning: orphan data file 'meta/b/foo/apple/00manifest.i'
607 warning: orphan data file 'meta/b/foo/apple/bees/00manifest.i'
608 608 crosschecking files in changesets and manifests
609 609 b/bar/fruits.txt@0: in changeset but not in manifest
610 610 b/bar/orange/fly/gnat.py@0: in changeset but not in manifest
611 611 b/bar/orange/fly/housefly.txt@0: in changeset but not in manifest
612 612 b/foo/apple/bees/flower.py@0: in changeset but not in manifest
613 613 checking files
614 614 8 files, 4 changesets, 18 total revisions
615 615 6 warnings encountered!
616 616 9 integrity errors encountered!
617 617 (first damaged changeset appears to be 0)
618 618 [1]
619 619 $ cp -R .hg/store-newcopy/. .hg/store
620 620
621 621 Verify reports missing dirlog entry
622 622 $ mv -f .hg/store-copy/meta/b/00manifest.* .hg/store/meta/b/
623 623 $ hg verify
624 624 checking changesets
625 625 checking manifests
626 626 checking directory manifests
627 627 b/@2: parent-directory manifest refers to unknown revision ac0d30948e0b
628 628 b/@3: parent-directory manifest refers to unknown revision 367152e6af28
629 629 b/bar/@?: rev 2 points to unexpected changeset 2
630 630 b/bar/@?: 44d7e1146e0d not in parent-directory manifest
631 631 b/bar/@?: rev 3 points to unexpected changeset 3
632 632 b/bar/@?: 70b10c6b17b7 not in parent-directory manifest
633 633 b/bar/orange/@?: rev 2 points to unexpected changeset 3
634 634 (expected None)
635 635 b/bar/orange/fly/@?: rev 2 points to unexpected changeset 3
636 636 (expected None)
637 637 crosschecking files in changesets and manifests
638 638 checking files
639 639 8 files, 4 changesets, 18 total revisions
640 640 2 warnings encountered!
641 641 8 integrity errors encountered!
642 642 (first damaged changeset appears to be 2)
643 643 [1]
644 644 $ cp -R .hg/store-newcopy/. .hg/store
645 645
646 646 Test cloning a treemanifest repo over http.
647 647 $ hg serve -p $HGPORT -d --pid-file=hg.pid --errorlog=errors.log
648 648 $ cat hg.pid >> $DAEMON_PIDS
649 649 $ cd ..
650 650 We can clone even with the knob turned off and we'll get a treemanifest repo.
651 651 $ hg clone --config experimental.treemanifest=False \
652 652 > --config experimental.changegroup3=True \
653 653 > http://localhost:$HGPORT deepclone
654 654 requesting all changes
655 655 adding changesets
656 656 adding manifests
657 657 adding file changes
658 658 added 4 changesets with 18 changes to 8 files
659 659 new changesets 775704be6f52:523e5c631710
660 660 updating to branch default
661 661 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
662 662 No server errors.
663 663 $ cat deeprepo/errors.log
664 664 requires got updated to include treemanifest
665 665 $ cat deepclone/.hg/requires | grep treemanifest
666 666 treemanifest
667 667 Tree manifest revlogs exist.
668 668 $ find deepclone/.hg/store/meta | sort
669 669 deepclone/.hg/store/meta
670 670 deepclone/.hg/store/meta/b
671 671 deepclone/.hg/store/meta/b/00manifest.i
672 672 deepclone/.hg/store/meta/b/bar
673 673 deepclone/.hg/store/meta/b/bar/00manifest.i
674 674 deepclone/.hg/store/meta/b/bar/orange
675 675 deepclone/.hg/store/meta/b/bar/orange/00manifest.i
676 676 deepclone/.hg/store/meta/b/bar/orange/fly
677 677 deepclone/.hg/store/meta/b/bar/orange/fly/00manifest.i
678 678 deepclone/.hg/store/meta/b/foo
679 679 deepclone/.hg/store/meta/b/foo/00manifest.i
680 680 deepclone/.hg/store/meta/b/foo/apple
681 681 deepclone/.hg/store/meta/b/foo/apple/00manifest.i
682 682 deepclone/.hg/store/meta/b/foo/apple/bees
683 683 deepclone/.hg/store/meta/b/foo/apple/bees/00manifest.i
684 684 deepclone/.hg/store/meta/~2e_a
685 685 deepclone/.hg/store/meta/~2e_a/00manifest.i
686 686 Verify passes.
687 687 $ cd deepclone
688 688 $ hg verify
689 689 checking changesets
690 690 checking manifests
691 691 checking directory manifests
692 692 crosschecking files in changesets and manifests
693 693 checking files
694 694 8 files, 4 changesets, 18 total revisions
695 695 $ cd ..
696 696
697 697 Create clones using old repo formats to use in later tests
698 698 $ hg clone --config format.usestore=False \
699 699 > --config experimental.changegroup3=True \
700 700 > http://localhost:$HGPORT deeprepo-basicstore
701 701 requesting all changes
702 702 adding changesets
703 703 adding manifests
704 704 adding file changes
705 705 added 4 changesets with 18 changes to 8 files
706 706 new changesets 775704be6f52:523e5c631710
707 707 updating to branch default
708 708 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
709 709 $ cd deeprepo-basicstore
710 710 $ grep store .hg/requires
711 711 [1]
712 712 $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --errorlog=errors.log
713 713 $ cat hg.pid >> $DAEMON_PIDS
714 714 $ cd ..
715 715 $ hg clone --config format.usefncache=False \
716 716 > --config experimental.changegroup3=True \
717 717 > http://localhost:$HGPORT deeprepo-encodedstore
718 718 requesting all changes
719 719 adding changesets
720 720 adding manifests
721 721 adding file changes
722 722 added 4 changesets with 18 changes to 8 files
723 723 new changesets 775704be6f52:523e5c631710
724 724 updating to branch default
725 725 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
726 726 $ cd deeprepo-encodedstore
727 727 $ grep fncache .hg/requires
728 728 [1]
729 729 $ hg serve -p $HGPORT2 -d --pid-file=hg.pid --errorlog=errors.log
730 730 $ cat hg.pid >> $DAEMON_PIDS
731 731 $ cd ..
732 732
733 733 Local clone with basicstore
734 734 $ hg clone -U deeprepo-basicstore local-clone-basicstore
735 735 $ hg -R local-clone-basicstore verify
736 736 checking changesets
737 737 checking manifests
738 738 checking directory manifests
739 739 crosschecking files in changesets and manifests
740 740 checking files
741 741 8 files, 4 changesets, 18 total revisions
742 742
743 743 Local clone with encodedstore
744 744 $ hg clone -U deeprepo-encodedstore local-clone-encodedstore
745 745 $ hg -R local-clone-encodedstore verify
746 746 checking changesets
747 747 checking manifests
748 748 checking directory manifests
749 749 crosschecking files in changesets and manifests
750 750 checking files
751 751 8 files, 4 changesets, 18 total revisions
752 752
753 753 Local clone with fncachestore
754 754 $ hg clone -U deeprepo local-clone-fncachestore
755 755 $ hg -R local-clone-fncachestore verify
756 756 checking changesets
757 757 checking manifests
758 758 checking directory manifests
759 759 crosschecking files in changesets and manifests
760 760 checking files
761 761 8 files, 4 changesets, 18 total revisions
762 762
763 763 Stream clone with basicstore
764 764 $ hg clone --config experimental.changegroup3=True --stream -U \
765 765 > http://localhost:$HGPORT1 stream-clone-basicstore
766 766 streaming all changes
767 767 18 files to transfer, * of data (glob)
768 768 transferred * in * seconds (*) (glob)
769 769 searching for changes
770 770 no changes found
771 771 $ hg -R stream-clone-basicstore verify
772 772 checking changesets
773 773 checking manifests
774 774 checking directory manifests
775 775 crosschecking files in changesets and manifests
776 776 checking files
777 777 8 files, 4 changesets, 18 total revisions
778 778
779 779 Stream clone with encodedstore
780 780 $ hg clone --config experimental.changegroup3=True --stream -U \
781 781 > http://localhost:$HGPORT2 stream-clone-encodedstore
782 782 streaming all changes
783 783 18 files to transfer, * of data (glob)
784 784 transferred * in * seconds (*) (glob)
785 785 searching for changes
786 786 no changes found
787 787 $ hg -R stream-clone-encodedstore verify
788 788 checking changesets
789 789 checking manifests
790 790 checking directory manifests
791 791 crosschecking files in changesets and manifests
792 792 checking files
793 793 8 files, 4 changesets, 18 total revisions
794 794
795 795 Stream clone with fncachestore
796 796 $ hg clone --config experimental.changegroup3=True --stream -U \
797 797 > http://localhost:$HGPORT stream-clone-fncachestore
798 798 streaming all changes
799 799 18 files to transfer, * of data (glob)
800 800 transferred * in * seconds (*) (glob)
801 801 searching for changes
802 802 no changes found
803 803 $ hg -R stream-clone-fncachestore verify
804 804 checking changesets
805 805 checking manifests
806 806 checking directory manifests
807 807 crosschecking files in changesets and manifests
808 808 checking files
809 809 8 files, 4 changesets, 18 total revisions
810 810
811 811 Packed bundle
812 812 $ hg -R deeprepo debugcreatestreamclonebundle repo-packed.hg
813 813 writing 5330 bytes for 18 files
814 814 bundle requirements: generaldelta, revlogv1, treemanifest
815 815 $ hg debugbundle --spec repo-packed.hg
816 816 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1%2Ctreemanifest
817 817
818 818 Bundle with changegroup2 is not supported
819 819
820 820 $ hg -R deeprepo bundle --all -t v2 deeprepo.bundle
821 821 abort: repository does not support bundle version 02
822 822 [255]
823 823
824 824 Pull does not include changegroup for manifest the client already has from
825 825 other branch
826 826
827 827 $ mkdir grafted-dir-repo
828 828 $ cd grafted-dir-repo
829 829 $ hg --config experimental.treemanifest=1 init
830 830 $ mkdir dir
831 831 $ echo a > dir/file
832 832 $ echo a > file
833 833 $ hg ci -Am initial
834 834 adding dir/file
835 835 adding file
836 836 $ echo b > dir/file
837 837 $ hg ci -m updated
838 838 $ hg co '.^'
839 839 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
840 840 $ hg revert -r tip dir/
841 841 reverting dir/file
842 842 $ echo b > file # to make sure root manifest is sent
843 843 $ hg ci -m grafted
844 844 created new head
845 845 $ cd ..
846 846
847 847 $ hg --config experimental.treemanifest=1 clone --pull -r 1 \
848 848 > grafted-dir-repo grafted-dir-repo-clone
849 849 adding changesets
850 850 adding manifests
851 851 adding file changes
852 852 added 2 changesets with 3 changes to 2 files
853 853 new changesets d84f4c419457:09ab742f3b0f
854 854 updating to branch default
855 855 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
856 856 $ cd grafted-dir-repo-clone
857 857 $ hg pull -r 2
858 858 pulling from $TESTTMP/grafted-dir-repo
859 859 searching for changes
860 860 adding changesets
861 861 adding manifests
862 862 adding file changes
863 863 added 1 changesets with 1 changes to 1 files (+1 heads)
864 864 new changesets 73699489fb7c
865 865 (run 'hg heads' to see heads, 'hg merge' to merge)
866 866
867 867 Committing a empty commit does not duplicate root treemanifest
868 868 $ echo z >> z
869 869 $ hg commit -Aqm 'pre-empty commit'
870 870 $ hg rm z
871 871 $ hg commit --amend -m 'empty commit'
872 872 saved backup bundle to $TESTTMP/grafted-dir-repo-clone/.hg/strip-backup/cb99d5717cea-9e3b6b02-amend.hg
873 873 $ hg log -r 'tip + tip^' -T '{manifest}\n'
874 874 1:678d3574b88c
875 875 1:678d3574b88c
876 876 $ hg --config extensions.strip= strip -r . -q
@@ -1,363 +1,363 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 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 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 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 105 file@0: manifest refers to unknown revision 362fef284ce2
106 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 warning: orphan revlog 'data/file.i'
119 warning: orphan data file '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 133 file@0: manifest refers to unknown revision 362fef284ce2
134 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 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 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 warning: orphan revlog 'data/a.i'
299 warning: orphan data file '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 ..
320 320
321 321 test flag processor and skipflags
322 322
323 323 $ hg init skipflags
324 324 $ cd skipflags
325 325 $ cat >> .hg/hgrc <<EOF
326 326 > [extensions]
327 327 > flagprocessor=$RUNTESTDIR/flagprocessorext.py
328 328 > EOF
329 329 $ echo '[BASE64]content' > base64
330 330 $ hg commit -Aqm 'flag processor content' base64
331 331 $ hg verify
332 332 checking changesets
333 333 checking manifests
334 334 crosschecking files in changesets and manifests
335 335 checking files
336 336 1 files, 1 changesets, 1 total revisions
337 337
338 338 $ cat >> $TESTTMP/break-base64.py <<EOF
339 339 > from __future__ import absolute_import
340 340 > import base64
341 341 > base64.b64decode=lambda x: x
342 342 > EOF
343 343 $ cat >> .hg/hgrc <<EOF
344 344 > breakbase64=$TESTTMP/break-base64.py
345 345 > EOF
346 346
347 347 $ hg verify
348 348 checking changesets
349 349 checking manifests
350 350 crosschecking files in changesets and manifests
351 351 checking files
352 352 base64@0: unpacking 794cee7777cb: integrity check failed on data/base64.i:0
353 353 1 files, 1 changesets, 1 total revisions
354 354 1 integrity errors encountered!
355 355 (first damaged changeset appears to be 0)
356 356 [1]
357 357 $ hg verify --config verify.skipflags=2147483647
358 358 checking changesets
359 359 checking manifests
360 360 crosschecking files in changesets and manifests
361 361 checking files
362 362 1 files, 1 changesets, 1 total revisions
363 363
General Comments 0
You need to be logged in to leave comments. Login now