annotate mercurial/verify.py @ 6858:8f256bf98219

Add support for multiple possible bisect results (issue1228, issue1182) The real reason for both issue is that bisect can not handle cases where there are multiple possibilities for the result. Example (from issue1228): rev 0 -> good rev 1 -> skipped rev 2 -> skipped rev 3 -> skipped rev 4 -> bad Note that this patch does not only fix the reported Assertion Error but also the problem of a non converging bisect: hg init for i in `seq 3`; do echo $i > $i; hg add $i; hg ci -m$i; done hg bisect -b 2 hg bisect -g 0 hg bisect -s From this state on, you can: a) mark as bad forever (non converging!) b) mark as good to get an inconsistent state c) skip for the Assertion Error Minor description and code edits by pmezard.
author Bernhard Leiner <bleiner@gmail.com>
date Sat, 02 Aug 2008 22:10:10 +0200
parents 9b35a9f34675
children fb42030d79d6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 # verify.py - repository integrity checking for Mercurial
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4395
diff changeset
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 # of the GNU General Public License, incorporated herein by reference.
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
6211
f89fd07fc51d Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents: 5541
diff changeset
8 from node import nullid, short
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3744
diff changeset
9 from i18n import _
5175
012dbf88b9b2 remove unneeded imports of mdiff
Matt Mackall <mpm@selenic.com>
parents: 4915
diff changeset
10 import revlog
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
11
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
12 def verify(repo):
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
13 lock = repo.lock()
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
14 try:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
15 return _verify(repo)
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
16 finally:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
17 del lock
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
18
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
19 def _verify(repo):
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
20 filelinkrevs = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
21 filenodes = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
22 changesets = revisions = files = 0
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
23 firstbad = [None]
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
24 errors = [0]
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
25 warnings = [0]
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
26 neededmanifests = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
27
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
28 def err(linkrev, msg, filename=None):
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
29 if linkrev != None:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
30 if firstbad[0] != None:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
31 firstbad[0] = min(firstbad[0], linkrev)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
32 else:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
33 firstbad[0] = linkrev
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
34 else:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
35 linkrev = "?"
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
36 msg = "%s: %s" % (linkrev, msg)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
37 if filename:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
38 msg = "%s@%s" % (filename, msg)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
39 repo.ui.warn(" " + msg + "\n")
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
40 errors[0] += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
41
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
42 def warn(msg):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
43 repo.ui.warn(msg + "\n")
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
44 warnings[0] += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
45
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
46 def checksize(obj, name):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
47 d = obj.checksize()
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
48 if d[0]:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
49 err(None, _("data length off by %d bytes") % d[0], name)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
50 if d[1]:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
51 err(None, _("index contains %d extra bytes") % d[1], name)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
52
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
53 def checkversion(obj, name):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
54 if obj.version != revlog.REVLOGV0:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
55 if not revlogv1:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
56 warn(_("warning: `%s' uses revlog format 1") % name)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
57 elif revlogv1:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
58 warn(_("warning: `%s' uses revlog format 0") % name)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
59
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 3891
diff changeset
60 revlogv1 = repo.changelog.version != revlog.REVLOGV0
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 3891
diff changeset
61 if repo.ui.verbose or not revlogv1:
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
62 repo.ui.status(_("repository uses revlog format %d\n") %
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
63 (revlogv1 and 1 or 0))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
64
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
65 havecl = havemf = 1
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
66 seen = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
67 repo.ui.status(_("checking changesets\n"))
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
68 if repo.changelog.count() == 0 and repo.manifest.count() > 1:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
69 havecl = 0
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
70 err(0, _("empty or missing 00changelog.i"))
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
71 else:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
72 checksize(repo.changelog, "changelog")
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73
3473
0e68608bd11d use xrange instead of range
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3196
diff changeset
74 for i in xrange(repo.changelog.count()):
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75 changesets += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
76 n = repo.changelog.node(i)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
77 l = repo.changelog.linkrev(n)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
78 if l != i:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
79 err(i, _("incorrect link (%d) for changeset") %(l))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
80 if n in seen:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
81 err(i, _("duplicates changeset at revision %d") % seen[n])
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
82 seen[n] = i
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
83
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
84 for p in repo.changelog.parents(n):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
85 if p not in repo.changelog.nodemap:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
86 err(i, _("changeset has unknown parent %s") % short(p))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
87 try:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
88 changes = repo.changelog.read(n)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
89 except KeyboardInterrupt:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
90 repo.ui.warn(_("interrupted"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
91 raise
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
92 except Exception, inst:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
93 err(i, _("unpacking changeset: %s") % inst)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
94 continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
95
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
96 if changes[0] not in neededmanifests:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
97 neededmanifests[changes[0]] = i
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
98
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
99 for f in changes[3]:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
100 filelinkrevs.setdefault(f, []).append(i)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
101
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
102 seen = {}
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
103 repo.ui.status(_("checking manifests\n"))
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
104 if repo.changelog.count() > 0 and repo.manifest.count() == 0:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
105 havemf = 0
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
106 err(0, _("empty or missing 00manifest.i"))
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
107 else:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
108 checkversion(repo.manifest, "manifest")
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
109 checksize(repo.manifest, "manifest")
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
110
3473
0e68608bd11d use xrange instead of range
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3196
diff changeset
111 for i in xrange(repo.manifest.count()):
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
112 n = repo.manifest.node(i)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
113 l = repo.manifest.linkrev(n)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
114
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
115 if l < 0 or (havecl and l >= repo.changelog.count()):
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
116 err(None, _("bad link (%d) at manifest revision %d") % (l, i))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
117
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
118 if n in neededmanifests:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
119 del neededmanifests[n]
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
120
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
121 if n in seen:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
122 err(l, _("duplicates manifest from %d") % seen[n])
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
123
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
124 seen[n] = l
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
125
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
126 for p in repo.manifest.parents(n):
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
127 if p not in repo.manifest.nodemap:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
128 err(l, _("manifest has unknown parent %s") % short(p))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
129
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
130 try:
3196
f3b939444c72 Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents: 2778
diff changeset
131 for f, fn in repo.manifest.readdelta(n).iteritems():
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
132 fns = filenodes.setdefault(f, {})
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
133 if fn not in fns:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
134 fns[fn] = n
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
135 except KeyboardInterrupt:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
136 repo.ui.warn(_("interrupted"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
137 raise
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
138 except Exception, inst:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
139 err(l, _("reading manifest delta: %s") % inst)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
140 continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
141
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
142 repo.ui.status(_("crosschecking files in changesets and manifests\n"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
143
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
144 if havemf > 0:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
145 nm = [(c, m) for m, c in neededmanifests.items()]
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
146 nm.sort()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
147 for c, m in nm:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
148 err(c, _("changeset refers to unknown manifest %s") % short(m))
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
149 del neededmanifests, nm
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
150
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
151 if havecl:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
152 fl = filenodes.keys()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
153 fl.sort()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
154 for f in fl:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
155 if f not in filelinkrevs:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
156 lrs = [repo.manifest.linkrev(n) for n in filenodes[f]]
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
157 lrs.sort()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
158 err(lrs[0], _("in manifest but not in changeset"), f)
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
159 del fl
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
160
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
161 if havemf:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
162 fl = filelinkrevs.keys()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
163 fl.sort()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
164 for f in fl:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
165 if f not in filenodes:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
166 lr = filelinkrevs[f][0]
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
167 err(lr, _("in changeset but not in manifest"), f)
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
168 del fl
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
169
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
170 repo.ui.status(_("checking files\n"))
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
171 ff = dict.fromkeys(filenodes.keys() + filelinkrevs.keys()).keys()
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
172 ff.sort()
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
173 for f in ff:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
174 if f == "/dev/null":
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
175 continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
176 files += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
177 if not f:
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
178 lr = filelinkrevs[f][0]
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
179 err(lr, _("file without name in manifest"))
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
180 continue
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
181 fl = repo.file(f)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
182 checkversion(fl, f)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
183 checksize(fl, f)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
184
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
185 if fl.count() == 0:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
186 err(filelinkrevs[f][0], _("empty or missing revlog"), f)
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
187 continue
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
188
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
189 seen = {}
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
190 nodes = {nullid: 1}
3473
0e68608bd11d use xrange instead of range
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3196
diff changeset
191 for i in xrange(fl.count()):
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
192 revisions += 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
193 n = fl.node(i)
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
194 flr = fl.linkrev(n)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
195
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
196 if flr < 0 or (havecl and flr not in filelinkrevs.get(f, [])):
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
197 if flr < 0 or flr >= repo.changelog.count():
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
198 err(None, _("rev %d point to nonexistent changeset %d")
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
199 % (i, flr), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
200 else:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
201 err(None, _("rev %d points to unexpected changeset %d")
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
202 % (i, flr), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
203 if f in filelinkrevs:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
204 warn(_(" (expected %s)") % filelinkrevs[f][0])
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
205 flr = None # can't be trusted
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
206 else:
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
207 if havecl:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
208 filelinkrevs[f].remove(flr)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
209
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
210 if n in seen:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
211 err(flr, _("duplicate revision %d") % i, f)
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
212 if f in filenodes:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
213 if havemf and n not in filenodes[f]:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
214 err(flr, _("%s not in manifests") % (short(n)), f)
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
215 else:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
216 del filenodes[f][n]
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
217
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
218 # verify contents
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
219 try:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
220 t = fl.read(n)
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
221 except KeyboardInterrupt:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
222 repo.ui.warn(_("interrupted"))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
223 raise
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
224 except Exception, inst:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
225 err(flr, _("unpacking %s: %s") % (short(n), inst), f)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
226
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
227 # verify parents
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
228 try:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
229 (p1, p2) = fl.parents(n)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
230 if p1 not in nodes:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
231 err(flr, _("unknown parent 1 %s of %s") %
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
232 (short(p1), short(n)), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
233 if p2 not in nodes:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
234 err(flr, _("unknown parent 2 %s of %s") %
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
235 (short(p2), short(p1)), f)
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
236 except KeyboardInterrupt:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
237 repo.ui.warn(_("interrupted"))
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
238 raise
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
239 except Exception, inst:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
240 err(flr, _("checking parents of %s: %s") % (short(n), inst), f)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
241 nodes[n] = 1
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
242
3744
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
243 # check renames
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
244 try:
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
245 rp = fl.renamed(n)
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
246 if rp:
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
247 fl2 = repo.file(rp[0])
6534
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
248 if fl2.count() == 0:
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
249 err(flr, _("empty or missing copy source revlog %s:%s")
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
250 % (rp[0], short(rp[1])), f)
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
251 elif rp[1] == nullid:
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
252 err(flr, _("copy source revision is nullid %s:%s")
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
253 % (rp[0], short(rp[1])), f)
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
254 else:
9b35a9f34675 verify: check copy source revlog and nodeid
Patrick Mezard <pmezard@gmail.com>
parents: 6211
diff changeset
255 rev = fl2.rev(rp[1])
3744
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
256 except KeyboardInterrupt:
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
257 repo.ui.warn(_("interrupted"))
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
258 raise
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
259 except Exception, inst:
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
260 err(flr, _("checking rename of %s: %s") %
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
261 (short(n), inst), f)
3744
d626fc9e3985 verify: add rename link checking
Matt Mackall <mpm@selenic.com>
parents: 3473
diff changeset
262
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
263 # cross-check
5541
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
264 if f in filenodes:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
265 fns = [(repo.manifest.linkrev(filenodes[f][n]), n)
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
266 for n in filenodes[f]]
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
267 fns.sort()
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
268 for lr, node in fns:
ceaa752fa316 verify: improve handling of empty or missing files
Matt Mackall <mpm@selenic.com>
parents: 5313
diff changeset
269 err(lr, _("%s in manifests not found") % short(node), f)
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
270
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
271 repo.ui.status(_("%d files, %d changesets, %d total revisions\n") %
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
272 (files, changesets, revisions))
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
273
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
274 if warnings[0]:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
275 repo.ui.warn(_("%d warnings encountered!\n") % warnings[0])
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
276 if errors[0]:
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
277 repo.ui.warn(_("%d integrity errors encountered!\n") % errors[0])
5313
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
278 if firstbad[0]:
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
279 repo.ui.warn(_("(first damaged changeset appears to be %d)\n")
29be4228303b verify: report first bad changeset
Matt Mackall <mpm@selenic.com>
parents: 5179
diff changeset
280 % firstbad[0])
2778
fdc232d8a193 Move repo.verify
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
281 return 1