114 r = repo.changelog.rev(n) |
114 r = repo.changelog.rev(n) |
115 except KeyError: |
115 except KeyError: |
116 r = "?" |
116 r = "?" |
117 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n)) |
117 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n)) |
118 |
118 |
119 elif cmd == "verify": |
|
120 filelinkrevs = {} |
|
121 filenodes = {} |
|
122 manifestchangeset = {} |
|
123 changesets = revisions = files = 0 |
|
124 errors = 0 |
|
125 |
|
126 ui.status("checking changesets\n") |
|
127 for i in range(repo.changelog.count()): |
|
128 changesets += 1 |
|
129 n = repo.changelog.node(i) |
|
130 for p in repo.changelog.parents(n): |
|
131 if p not in repo.changelog.nodemap: |
|
132 ui.warn("changeset %s has unknown parent %s\n" % |
|
133 (hg.short(n), hg.short(p))) |
|
134 errors += 1 |
|
135 try: |
|
136 changes = repo.changelog.read(n) |
|
137 except Exception, inst: |
|
138 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst)) |
|
139 errors += 1 |
|
140 |
|
141 manifestchangeset[changes[0]] = n |
|
142 for f in changes[3]: |
|
143 filelinkrevs.setdefault(f, []).append(i) |
|
144 |
|
145 ui.status("checking manifests\n") |
|
146 for i in range(repo.manifest.count()): |
|
147 n = repo.manifest.node(i) |
|
148 for p in repo.manifest.parents(n): |
|
149 if p not in repo.manifest.nodemap: |
|
150 ui.warn("manifest %s has unknown parent %s\n" % |
|
151 (hg.short(n), hg.short(p))) |
|
152 errors += 1 |
|
153 ca = repo.changelog.node(repo.manifest.linkrev(n)) |
|
154 cc = manifestchangeset[n] |
|
155 if ca != cc: |
|
156 ui.warn("manifest %s points to %s, not %s\n" % |
|
157 (hg.hex(n), hg.hex(ca), hg.hex(cc))) |
|
158 errors += 1 |
|
159 |
|
160 try: |
|
161 delta = mdiff.patchtext(repo.manifest.delta(n)) |
|
162 except KeyboardInterrupt: |
|
163 print "aborted" |
|
164 sys.exit(0) |
|
165 except Exception, inst: |
|
166 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst)) |
|
167 errors += 1 |
|
168 |
|
169 ff = [ l.split('\0') for l in delta.splitlines() ] |
|
170 for f, fn in ff: |
|
171 filenodes.setdefault(f, {})[hg.bin(fn)] = 1 |
|
172 |
|
173 ui.status("crosschecking files in changesets and manifests\n") |
|
174 for f in filenodes: |
|
175 if f not in filelinkrevs: |
|
176 ui.warn("file %s in manifest but not in changesets\n" % f) |
|
177 errors += 1 |
|
178 |
|
179 for f in filelinkrevs: |
|
180 if f not in filenodes: |
|
181 ui.warn("file %s in changeset but not in manifest\n" % f) |
|
182 errors += 1 |
|
183 |
|
184 ui.status("checking files\n") |
|
185 ff = filenodes.keys() |
|
186 ff.sort() |
|
187 for f in ff: |
|
188 if f == "/dev/null": continue |
|
189 files += 1 |
|
190 fl = repo.file(f) |
|
191 nodes = { hg.nullid: 1 } |
|
192 for i in range(fl.count()): |
|
193 revisions += 1 |
|
194 n = fl.node(i) |
|
195 |
|
196 if n not in filenodes[f]: |
|
197 ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n))) |
|
198 print len(filenodes[f].keys()), fl.count(), f |
|
199 errors += 1 |
|
200 else: |
|
201 del filenodes[f][n] |
|
202 |
|
203 flr = fl.linkrev(n) |
|
204 if flr not in filelinkrevs[f]: |
|
205 ui.warn("%s:%s points to unexpected changeset rev %d\n" |
|
206 % (f, hg.short(n), fl.linkrev(n))) |
|
207 errors += 1 |
|
208 else: |
|
209 filelinkrevs[f].remove(flr) |
|
210 |
|
211 # verify contents |
|
212 try: |
|
213 t = fl.read(n) |
|
214 except Exception, inst: |
|
215 ui.warn("unpacking file %s %s: %s\n" % (f, hg.short(n), inst)) |
|
216 errors += 1 |
|
217 |
|
218 # verify parents |
|
219 (p1, p2) = fl.parents(n) |
|
220 if p1 not in nodes: |
|
221 ui.warn("file %s:%s unknown parent 1 %s" % |
|
222 (f, hg.short(n), hg.short(p1))) |
|
223 errors += 1 |
|
224 if p2 not in nodes: |
|
225 ui.warn("file %s:%s unknown parent 2 %s" % |
|
226 (f, hg.short(n), hg.short(p1))) |
|
227 errors += 1 |
|
228 nodes[n] = 1 |
|
229 |
|
230 # cross-check |
|
231 for node in filenodes[f]: |
|
232 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f)) |
|
233 errors += 1 |
|
234 |
|
235 ui.status("%d files, %d changesets, %d total revisions\n" % |
|
236 (files, changesets, revisions)) |
|
237 |
|
238 if errors: |
|
239 ui.warn("%d integrity errors encountered!\n" % errors) |
|
240 sys.exit(1) |
|
241 |
|
242 else: |
119 else: |
243 if cmd: ui.warn("unknown command\n\n") |
120 if cmd: ui.warn("unknown command\n\n") |
244 sys.exit(1) |
121 sys.exit(1) |