Mercurial > hg > mercurial-crew-with-dirclash
annotate mercurial/verify.py @ 3570:c141d07198b9
Inform the user about the new URL when being redirected via http.
Additionally the changed code ensures that the new URL is used,
even if it doesn't end with the query string.
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Sat, 28 Oct 2006 23:05:57 +0200 |
parents | 0e68608bd11d |
children | d626fc9e3985 |
rev | line source |
---|---|
2802 | 1 # verify.py - repository integrity checking for Mercurial |
2 # | |
3 # Copyright 2006 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms | |
6 # of the GNU General Public License, incorporated herein by reference. | |
7 | |
8 from node import * | |
9 from i18n import gettext as _ | |
10 import revlog, mdiff | |
11 | |
12 def verify(repo): | |
13 filelinkrevs = {} | |
14 filenodes = {} | |
15 changesets = revisions = files = 0 | |
16 errors = [0] | |
17 warnings = [0] | |
18 neededmanifests = {} | |
19 | |
20 def err(msg): | |
21 repo.ui.warn(msg + "\n") | |
22 errors[0] += 1 | |
23 | |
24 def warn(msg): | |
25 repo.ui.warn(msg + "\n") | |
26 warnings[0] += 1 | |
27 | |
28 def checksize(obj, name): | |
29 d = obj.checksize() | |
30 if d[0]: | |
31 err(_("%s data length off by %d bytes") % (name, d[0])) | |
32 if d[1]: | |
33 err(_("%s index contains %d extra bytes") % (name, d[1])) | |
34 | |
35 def checkversion(obj, name): | |
36 if obj.version != revlog.REVLOGV0: | |
37 if not revlogv1: | |
38 warn(_("warning: `%s' uses revlog format 1") % name) | |
39 elif revlogv1: | |
40 warn(_("warning: `%s' uses revlog format 0") % name) | |
41 | |
42 revlogv1 = repo.revlogversion != revlog.REVLOGV0 | |
43 if repo.ui.verbose or revlogv1 != repo.revlogv1: | |
44 repo.ui.status(_("repository uses revlog format %d\n") % | |
45 (revlogv1 and 1 or 0)) | |
46 | |
47 seen = {} | |
48 repo.ui.status(_("checking changesets\n")) | |
49 checksize(repo.changelog, "changelog") | |
50 | |
3468
0e68608bd11d
use xrange instead of range
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3189
diff
changeset
|
51 for i in xrange(repo.changelog.count()): |
2802 | 52 changesets += 1 |
53 n = repo.changelog.node(i) | |
54 l = repo.changelog.linkrev(n) | |
55 if l != i: | |
56 err(_("incorrect link (%d) for changeset revision %d") %(l, i)) | |
57 if n in seen: | |
58 err(_("duplicate changeset at revision %d") % i) | |
59 seen[n] = 1 | |
60 | |
61 for p in repo.changelog.parents(n): | |
62 if p not in repo.changelog.nodemap: | |
63 err(_("changeset %s has unknown parent %s") % | |
64 (short(n), short(p))) | |
65 try: | |
66 changes = repo.changelog.read(n) | |
67 except KeyboardInterrupt: | |
68 repo.ui.warn(_("interrupted")) | |
69 raise | |
70 except Exception, inst: | |
71 err(_("unpacking changeset %s: %s") % (short(n), inst)) | |
72 continue | |
73 | |
74 neededmanifests[changes[0]] = n | |
75 | |
76 for f in changes[3]: | |
77 filelinkrevs.setdefault(f, []).append(i) | |
78 | |
79 seen = {} | |
80 repo.ui.status(_("checking manifests\n")) | |
81 checkversion(repo.manifest, "manifest") | |
82 checksize(repo.manifest, "manifest") | |
83 | |
3468
0e68608bd11d
use xrange instead of range
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3189
diff
changeset
|
84 for i in xrange(repo.manifest.count()): |
2802 | 85 n = repo.manifest.node(i) |
86 l = repo.manifest.linkrev(n) | |
87 | |
88 if l < 0 or l >= repo.changelog.count(): | |
89 err(_("bad manifest link (%d) at revision %d") % (l, i)) | |
90 | |
91 if n in neededmanifests: | |
92 del neededmanifests[n] | |
93 | |
94 if n in seen: | |
95 err(_("duplicate manifest at revision %d") % i) | |
96 | |
97 seen[n] = 1 | |
98 | |
99 for p in repo.manifest.parents(n): | |
100 if p not in repo.manifest.nodemap: | |
101 err(_("manifest %s has unknown parent %s") % | |
102 (short(n), short(p))) | |
103 | |
104 try: | |
3189
f3b939444c72
Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents:
2802
diff
changeset
|
105 for f, fn in repo.manifest.readdelta(n).iteritems(): |
f3b939444c72
Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents:
2802
diff
changeset
|
106 filenodes.setdefault(f, {})[fn] = 1 |
2802 | 107 except KeyboardInterrupt: |
108 repo.ui.warn(_("interrupted")) | |
109 raise | |
110 except Exception, inst: | |
3189
f3b939444c72
Abstract manifest block parsing.
Brendan Cully <brendan@kublai.com>
parents:
2802
diff
changeset
|
111 err(_("reading delta for manifest %s: %s") % (short(n), inst)) |
2802 | 112 continue |
113 | |
114 repo.ui.status(_("crosschecking files in changesets and manifests\n")) | |
115 | |
116 for m, c in neededmanifests.items(): | |
117 err(_("Changeset %s refers to unknown manifest %s") % | |
118 (short(m), short(c))) | |
119 del neededmanifests | |
120 | |
121 for f in filenodes: | |
122 if f not in filelinkrevs: | |
123 err(_("file %s in manifest but not in changesets") % f) | |
124 | |
125 for f in filelinkrevs: | |
126 if f not in filenodes: | |
127 err(_("file %s in changeset but not in manifest") % f) | |
128 | |
129 repo.ui.status(_("checking files\n")) | |
130 ff = filenodes.keys() | |
131 ff.sort() | |
132 for f in ff: | |
133 if f == "/dev/null": | |
134 continue | |
135 files += 1 | |
136 if not f: | |
137 err(_("file without name in manifest %s") % short(n)) | |
138 continue | |
139 fl = repo.file(f) | |
140 checkversion(fl, f) | |
141 checksize(fl, f) | |
142 | |
143 nodes = {nullid: 1} | |
144 seen = {} | |
3468
0e68608bd11d
use xrange instead of range
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3189
diff
changeset
|
145 for i in xrange(fl.count()): |
2802 | 146 revisions += 1 |
147 n = fl.node(i) | |
148 | |
149 if n in seen: | |
150 err(_("%s: duplicate revision %d") % (f, i)) | |
151 if n not in filenodes[f]: | |
152 err(_("%s: %d:%s not in manifests") % (f, i, short(n))) | |
153 else: | |
154 del filenodes[f][n] | |
155 | |
156 flr = fl.linkrev(n) | |
157 if flr not in filelinkrevs.get(f, []): | |
158 err(_("%s:%s points to unexpected changeset %d") | |
159 % (f, short(n), flr)) | |
160 else: | |
161 filelinkrevs[f].remove(flr) | |
162 | |
163 # verify contents | |
164 try: | |
165 t = fl.read(n) | |
166 except KeyboardInterrupt: | |
167 repo.ui.warn(_("interrupted")) | |
168 raise | |
169 except Exception, inst: | |
170 err(_("unpacking file %s %s: %s") % (f, short(n), inst)) | |
171 | |
172 # verify parents | |
173 (p1, p2) = fl.parents(n) | |
174 if p1 not in nodes: | |
175 err(_("file %s:%s unknown parent 1 %s") % | |
176 (f, short(n), short(p1))) | |
177 if p2 not in nodes: | |
178 err(_("file %s:%s unknown parent 2 %s") % | |
179 (f, short(n), short(p1))) | |
180 nodes[n] = 1 | |
181 | |
182 # cross-check | |
183 for node in filenodes[f]: | |
184 err(_("node %s in manifests not in %s") % (hex(node), f)) | |
185 | |
186 repo.ui.status(_("%d files, %d changesets, %d total revisions\n") % | |
187 (files, changesets, revisions)) | |
188 | |
189 if warnings[0]: | |
190 repo.ui.warn(_("%d warnings encountered!\n") % warnings[0]) | |
191 if errors[0]: | |
192 repo.ui.warn(_("%d integrity errors encountered!\n") % errors[0]) | |
193 return 1 | |
194 |