Show More
@@ -17,7 +17,7 b'' | |||||
17 | # pass |
|
17 | # pass | |
18 |
|
18 | |||
19 | import sys |
|
19 | import sys | |
20 |
from mercurial import hg, |
|
20 | from mercurial import hg, fancyopts, ui, commands | |
21 |
|
21 | |||
22 | try: |
|
22 | try: | |
23 | sys.exit(commands.dispatch(sys.argv[1:])) |
|
23 | sys.exit(commands.dispatch(sys.argv[1:])) | |
@@ -116,129 +116,6 b' elif cmd == "tags":' | |||||
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) |
@@ -389,6 +389,10 b' def tip(ui, repo):' | |||||
389 | def undo(ui, repo): |
|
389 | def undo(ui, repo): | |
390 | repo.undo() |
|
390 | repo.undo() | |
391 |
|
391 | |||
|
392 | def verify(ui, repo): | |||
|
393 | """verify the integrity of the repository""" | |||
|
394 | return repo.verify() | |||
|
395 | ||||
392 | table = { |
|
396 | table = { | |
393 | "add": (add, [], "hg add [files]"), |
|
397 | "add": (add, [], "hg add [files]"), | |
394 | "addremove": (addremove, [], "hg addremove"), |
|
398 | "addremove": (addremove, [], "hg addremove"), | |
@@ -436,6 +440,7 b' table = {' | |||||
436 | "status": (status, [], 'hg status'), |
|
440 | "status": (status, [], 'hg status'), | |
437 | "tip": (tip, [], 'hg tip'), |
|
441 | "tip": (tip, [], 'hg tip'), | |
438 | "undo": (undo, [], 'hg undo'), |
|
442 | "undo": (undo, [], 'hg undo'), | |
|
443 | "verify": (verify, [], 'hg verify'), | |||
439 | } |
|
444 | } | |
440 |
|
445 | |||
441 | norepo = "init branch help" |
|
446 | norepo = "init branch help" |
@@ -993,6 +993,133 b' class localrepository:' | |||||
993 | os.unlink(b) |
|
993 | os.unlink(b) | |
994 | os.unlink(c) |
|
994 | os.unlink(c) | |
995 |
|
995 | |||
|
996 | def verify(self): | |||
|
997 | filelinkrevs = {} | |||
|
998 | filenodes = {} | |||
|
999 | manifestchangeset = {} | |||
|
1000 | changesets = revisions = files = 0 | |||
|
1001 | errors = 0 | |||
|
1002 | ||||
|
1003 | self.ui.status("checking changesets\n") | |||
|
1004 | for i in range(self.changelog.count()): | |||
|
1005 | changesets += 1 | |||
|
1006 | n = self.changelog.node(i) | |||
|
1007 | for p in self.changelog.parents(n): | |||
|
1008 | if p not in self.changelog.nodemap: | |||
|
1009 | self.ui.warn("changeset %s has unknown parent %s\n" % | |||
|
1010 | (short(n), short(p))) | |||
|
1011 | errors += 1 | |||
|
1012 | try: | |||
|
1013 | changes = self.changelog.read(n) | |||
|
1014 | except Exception, inst: | |||
|
1015 | self.ui.warn("unpacking changeset %s: %s\n" % (short(n), inst)) | |||
|
1016 | errors += 1 | |||
|
1017 | ||||
|
1018 | manifestchangeset[changes[0]] = n | |||
|
1019 | for f in changes[3]: | |||
|
1020 | filelinkrevs.setdefault(f, []).append(i) | |||
|
1021 | ||||
|
1022 | self.ui.status("checking manifests\n") | |||
|
1023 | for i in range(self.manifest.count()): | |||
|
1024 | n = self.manifest.node(i) | |||
|
1025 | for p in self.manifest.parents(n): | |||
|
1026 | if p not in self.manifest.nodemap: | |||
|
1027 | self.ui.warn("manifest %s has unknown parent %s\n" % | |||
|
1028 | (short(n), short(p))) | |||
|
1029 | errors += 1 | |||
|
1030 | ca = self.changelog.node(self.manifest.linkrev(n)) | |||
|
1031 | cc = manifestchangeset[n] | |||
|
1032 | if ca != cc: | |||
|
1033 | self.ui.warn("manifest %s points to %s, not %s\n" % | |||
|
1034 | (hex(n), hex(ca), hex(cc))) | |||
|
1035 | errors += 1 | |||
|
1036 | ||||
|
1037 | try: | |||
|
1038 | delta = mdiff.patchtext(self.manifest.delta(n)) | |||
|
1039 | except KeyboardInterrupt: | |||
|
1040 | print "aborted" | |||
|
1041 | sys.exit(0) | |||
|
1042 | except Exception, inst: | |||
|
1043 | self.ui.warn("unpacking manifest %s: %s\n" | |||
|
1044 | % (short(n), inst)) | |||
|
1045 | errors += 1 | |||
|
1046 | ||||
|
1047 | ff = [ l.split('\0') for l in delta.splitlines() ] | |||
|
1048 | for f, fn in ff: | |||
|
1049 | filenodes.setdefault(f, {})[bin(fn)] = 1 | |||
|
1050 | ||||
|
1051 | self.ui.status("crosschecking files in changesets and manifests\n") | |||
|
1052 | for f in filenodes: | |||
|
1053 | if f not in filelinkrevs: | |||
|
1054 | self.ui.warn("file %s in manifest but not in changesets\n" % f) | |||
|
1055 | errors += 1 | |||
|
1056 | ||||
|
1057 | for f in filelinkrevs: | |||
|
1058 | if f not in filenodes: | |||
|
1059 | self.ui.warn("file %s in changeset but not in manifest\n" % f) | |||
|
1060 | errors += 1 | |||
|
1061 | ||||
|
1062 | self.ui.status("checking files\n") | |||
|
1063 | ff = filenodes.keys() | |||
|
1064 | ff.sort() | |||
|
1065 | for f in ff: | |||
|
1066 | if f == "/dev/null": continue | |||
|
1067 | files += 1 | |||
|
1068 | fl = self.file(f) | |||
|
1069 | nodes = { nullid: 1 } | |||
|
1070 | for i in range(fl.count()): | |||
|
1071 | revisions += 1 | |||
|
1072 | n = fl.node(i) | |||
|
1073 | ||||
|
1074 | if n not in filenodes[f]: | |||
|
1075 | self.ui.warn("%s: %d:%s not in manifests\n" | |||
|
1076 | % (f, i, short(n))) | |||
|
1077 | print len(filenodes[f].keys()), fl.count(), f | |||
|
1078 | errors += 1 | |||
|
1079 | else: | |||
|
1080 | del filenodes[f][n] | |||
|
1081 | ||||
|
1082 | flr = fl.linkrev(n) | |||
|
1083 | if flr not in filelinkrevs[f]: | |||
|
1084 | self.ui.warn("%s:%s points to unexpected changeset %d\n" | |||
|
1085 | % (f, short(n), fl.linkrev(n))) | |||
|
1086 | errors += 1 | |||
|
1087 | else: | |||
|
1088 | filelinkrevs[f].remove(flr) | |||
|
1089 | ||||
|
1090 | # verify contents | |||
|
1091 | try: | |||
|
1092 | t = fl.read(n) | |||
|
1093 | except Exception, inst: | |||
|
1094 | self.ui.warn("unpacking file %s %s: %s\n" | |||
|
1095 | % (f, short(n), inst)) | |||
|
1096 | errors += 1 | |||
|
1097 | ||||
|
1098 | # verify parents | |||
|
1099 | (p1, p2) = fl.parents(n) | |||
|
1100 | if p1 not in nodes: | |||
|
1101 | self.ui.warn("file %s:%s unknown parent 1 %s" % | |||
|
1102 | (f, short(n), short(p1))) | |||
|
1103 | errors += 1 | |||
|
1104 | if p2 not in nodes: | |||
|
1105 | self.ui.warn("file %s:%s unknown parent 2 %s" % | |||
|
1106 | (f, short(n), short(p1))) | |||
|
1107 | errors += 1 | |||
|
1108 | nodes[n] = 1 | |||
|
1109 | ||||
|
1110 | # cross-check | |||
|
1111 | for node in filenodes[f]: | |||
|
1112 | self.ui.warn("node %s in manifests not in %s\n" | |||
|
1113 | % (hex(n), f)) | |||
|
1114 | errors += 1 | |||
|
1115 | ||||
|
1116 | self.ui.status("%d files, %d changesets, %d total revisions\n" % | |||
|
1117 | (files, changesets, revisions)) | |||
|
1118 | ||||
|
1119 | if errors: | |||
|
1120 | self.ui.warn("%d integrity errors encountered!\n" % errors) | |||
|
1121 | return 1 | |||
|
1122 | ||||
996 | class remoterepository: |
|
1123 | class remoterepository: | |
997 | def __init__(self, ui, path): |
|
1124 | def __init__(self, ui, path): | |
998 | self.url = path |
|
1125 | self.url = path |
General Comments 0
You need to be logged in to leave comments.
Login now