comparison mercurial/localrepo.py @ 1383:3d6d45faf8b2

hg verify: add an error reporting helper function
author Matt Mackall <mpm@selenic.com>
date Wed, 05 Oct 2005 10:51:02 -0700
parents b113e7db06e9
children d729850d52fa
comparison
equal deleted inserted replaced
1382:b113e7db06e9 1383:3d6d45faf8b2
1307 1307
1308 def verify(self): 1308 def verify(self):
1309 filelinkrevs = {} 1309 filelinkrevs = {}
1310 filenodes = {} 1310 filenodes = {}
1311 changesets = revisions = files = 0 1311 changesets = revisions = files = 0
1312 errors = 0 1312 errors = [0]
1313 neededmanifests = {} 1313 neededmanifests = {}
1314
1315 def err(msg):
1316 self.ui.warn(msg + "\n")
1317 errors[0] += 1
1314 1318
1315 seen = {} 1319 seen = {}
1316 self.ui.status("checking changesets\n") 1320 self.ui.status("checking changesets\n")
1317 for i in range(self.changelog.count()): 1321 for i in range(self.changelog.count()):
1318 changesets += 1 1322 changesets += 1
1319 n = self.changelog.node(i) 1323 n = self.changelog.node(i)
1320 l = self.changelog.linkrev(n) 1324 l = self.changelog.linkrev(n)
1321 if l != i: 1325 if l != i:
1322 self.ui.warn("incorrect linkrev (%d) for changeset revision %d" 1326 err("incorrect link (%d) for changeset revision %d" % (l, i))
1323 % (l, i))
1324 if n in seen: 1327 if n in seen:
1325 self.ui.warn("duplicate changeset at revision %d\n" % i) 1328 err("duplicate changeset at revision %d" % i)
1326 errors += 1
1327 seen[n] = 1 1329 seen[n] = 1
1328 1330
1329 for p in self.changelog.parents(n): 1331 for p in self.changelog.parents(n):
1330 if p not in self.changelog.nodemap: 1332 if p not in self.changelog.nodemap:
1331 self.ui.warn("changeset %s has unknown parent %s\n" % 1333 err("changeset %s has unknown parent %s" %
1332 (short(n), short(p))) 1334 (short(n), short(p)))
1333 errors += 1
1334 try: 1335 try:
1335 changes = self.changelog.read(n) 1336 changes = self.changelog.read(n)
1336 except Exception, inst: 1337 except Exception, inst:
1337 self.ui.warn("unpacking changeset %s: %s\n" % (short(n), inst)) 1338 err("unpacking changeset %s: %s" % (short(n), inst))
1338 errors += 1
1339 1339
1340 neededmanifests[changes[0]] = n 1340 neededmanifests[changes[0]] = n
1341 1341
1342 for f in changes[3]: 1342 for f in changes[3]:
1343 filelinkrevs.setdefault(f, []).append(i) 1343 filelinkrevs.setdefault(f, []).append(i)
1347 for i in range(self.manifest.count()): 1347 for i in range(self.manifest.count()):
1348 n = self.manifest.node(i) 1348 n = self.manifest.node(i)
1349 l = self.manifest.linkrev(n) 1349 l = self.manifest.linkrev(n)
1350 1350
1351 if l < 0 or l >= self.changelog.count(): 1351 if l < 0 or l >= self.changelog.count():
1352 self.ui.warn("bad manifest link (%d) at revision %d\n" % 1352 err("bad manifest link (%d) at revision %d" % (l, i))
1353 (l, i))
1354 errors += 1
1355 1353
1356 if n in neededmanifests: 1354 if n in neededmanifests:
1357 del neededmanifests[n] 1355 del neededmanifests[n]
1358 1356
1359 if n in seen: 1357 if n in seen:
1360 self.ui.warn("duplicate manifest at revision %d\n" % i) 1358 err("duplicate manifest at revision %d" % i)
1361 errors += 1 1359
1362 seen[n] = 1 1360 seen[n] = 1
1363 1361
1364 for p in self.manifest.parents(n): 1362 for p in self.manifest.parents(n):
1365 if p not in self.manifest.nodemap: 1363 if p not in self.manifest.nodemap:
1366 self.ui.warn("manifest %s has unknown parent %s\n" % 1364 err("manifest %s has unknown parent %s" %
1367 (short(n), short(p))) 1365 (short(n), short(p)))
1368 errors += 1
1369 1366
1370 try: 1367 try:
1371 delta = mdiff.patchtext(self.manifest.delta(n)) 1368 delta = mdiff.patchtext(self.manifest.delta(n))
1372 except KeyboardInterrupt: 1369 except KeyboardInterrupt:
1373 self.ui.warn("interrupted") 1370 self.ui.warn("interrupted")
1374 raise 1371 raise
1375 except Exception, inst: 1372 except Exception, inst:
1376 self.ui.warn("unpacking manifest %s: %s\n" 1373 err("unpacking manifest %s: %s" % (short(n), inst))
1377 % (short(n), inst))
1378 errors += 1
1379 1374
1380 ff = [ l.split('\0') for l in delta.splitlines() ] 1375 ff = [ l.split('\0') for l in delta.splitlines() ]
1381 for f, fn in ff: 1376 for f, fn in ff:
1382 filenodes.setdefault(f, {})[bin(fn[:40])] = 1 1377 filenodes.setdefault(f, {})[bin(fn[:40])] = 1
1383 1378
1384 self.ui.status("crosschecking files in changesets and manifests\n") 1379 self.ui.status("crosschecking files in changesets and manifests\n")
1385 1380
1386 for m,c in neededmanifests.items(): 1381 for m,c in neededmanifests.items():
1387 self.ui.warn("Changeset %s refers to unknown manifest %s\n" 1382 err("Changeset %s refers to unknown manifest %s" % (m, c))
1388 % (m, c))
1389 errors += 1
1390 del neededmanifests 1383 del neededmanifests
1391 1384
1392 for f in filenodes: 1385 for f in filenodes:
1393 if f not in filelinkrevs: 1386 if f not in filelinkrevs:
1394 self.ui.warn("file %s in manifest but not in changesets\n" % f) 1387 err("file %s in manifest but not in changesets" % f)
1395 errors += 1
1396 1388
1397 for f in filelinkrevs: 1389 for f in filelinkrevs:
1398 if f not in filenodes: 1390 if f not in filenodes:
1399 self.ui.warn("file %s in changeset but not in manifest\n" % f) 1391 err("file %s in changeset but not in manifest" % f)
1400 errors += 1
1401 1392
1402 self.ui.status("checking files\n") 1393 self.ui.status("checking files\n")
1403 ff = filenodes.keys() 1394 ff = filenodes.keys()
1404 ff.sort() 1395 ff.sort()
1405 for f in ff: 1396 for f in ff:
1411 for i in range(fl.count()): 1402 for i in range(fl.count()):
1412 revisions += 1 1403 revisions += 1
1413 n = fl.node(i) 1404 n = fl.node(i)
1414 1405
1415 if n in seen: 1406 if n in seen:
1416 self.ui.warn("%s: duplicate revision %d\n" % (f, i)) 1407 err("%s: duplicate revision %d" % (f, i))
1417 errors += 1
1418
1419 if n not in filenodes[f]: 1408 if n not in filenodes[f]:
1420 self.ui.warn("%s: %d:%s not in manifests\n" 1409 err("%s: %d:%s not in manifests" % (f, i, short(n)))
1421 % (f, i, short(n)))
1422 errors += 1
1423 else: 1410 else:
1424 del filenodes[f][n] 1411 del filenodes[f][n]
1425 1412
1426 flr = fl.linkrev(n) 1413 flr = fl.linkrev(n)
1427 if flr not in filelinkrevs[f]: 1414 if flr not in filelinkrevs[f]:
1428 self.ui.warn("%s:%s points to unexpected changeset %d\n" 1415 err("%s:%s points to unexpected changeset %d"
1429 % (f, short(n), fl.linkrev(n))) 1416 % (f, short(n), flr))
1430 errors += 1
1431 else: 1417 else:
1432 filelinkrevs[f].remove(flr) 1418 filelinkrevs[f].remove(flr)
1433 1419
1434 # verify contents 1420 # verify contents
1435 try: 1421 try:
1436 t = fl.read(n) 1422 t = fl.read(n)
1437 except Exception, inst: 1423 except Exception, inst:
1438 self.ui.warn("unpacking file %s %s: %s\n" 1424 err("unpacking file %s %s: %s" % (f, short(n), inst))
1439 % (f, short(n), inst))
1440 errors += 1
1441 1425
1442 # verify parents 1426 # verify parents
1443 (p1, p2) = fl.parents(n) 1427 (p1, p2) = fl.parents(n)
1444 if p1 not in nodes: 1428 if p1 not in nodes:
1445 self.ui.warn("file %s:%s unknown parent 1 %s" % 1429 err("file %s:%s unknown parent 1 %s" %
1430 (f, short(n), short(p1)))
1431 if p2 not in nodes:
1432 err("file %s:%s unknown parent 2 %s" %
1446 (f, short(n), short(p1))) 1433 (f, short(n), short(p1)))
1447 errors += 1
1448 if p2 not in nodes:
1449 self.ui.warn("file %s:%s unknown parent 2 %s" %
1450 (f, short(n), short(p1)))
1451 errors += 1
1452 nodes[n] = 1 1434 nodes[n] = 1
1453 1435
1454 # cross-check 1436 # cross-check
1455 for node in filenodes[f]: 1437 for node in filenodes[f]:
1456 self.ui.warn("node %s in manifests not in %s\n" 1438 err("node %s in manifests not in %s" % (hex(node), f))
1457 % (hex(node), f))
1458 errors += 1
1459 1439
1460 self.ui.status("%d files, %d changesets, %d total revisions\n" % 1440 self.ui.status("%d files, %d changesets, %d total revisions\n" %
1461 (files, changesets, revisions)) 1441 (files, changesets, revisions))
1462 1442
1463 if errors: 1443 if errors[0]:
1464 self.ui.warn("%d integrity errors encountered!\n" % errors) 1444 self.ui.warn("%d integrity errors encountered!\n" % errors[0])
1465 return 1 1445 return 1