##// END OF EJS Templates
Fix two bugs in verify
mpm@selenic.com -
r93:0b0efe40 default
parent child Browse files
Show More
@@ -1,514 +1,514 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # mercurial - a minimal scalable distributed SCM
3 # mercurial - a minimal scalable distributed SCM
4 # v0.4f "jane dark"
4 # v0.4f "jane dark"
5 #
5 #
6 # Copyright 2005 Matt Mackall <mpm@selenic.com>
6 # Copyright 2005 Matt Mackall <mpm@selenic.com>
7 #
7 #
8 # This software may be used and distributed according to the terms
8 # This software may be used and distributed according to the terms
9 # of the GNU General Public License, incorporated herein by reference.
9 # of the GNU General Public License, incorporated herein by reference.
10
10
11 # the psyco compiler makes commits a bit faster
11 # the psyco compiler makes commits a bit faster
12 # and makes changegroup merge about 20 times slower!
12 # and makes changegroup merge about 20 times slower!
13 # try:
13 # try:
14 # import psyco
14 # import psyco
15 # psyco.full()
15 # psyco.full()
16 # except:
16 # except:
17 # pass
17 # pass
18
18
19 import sys, os, time
19 import sys, os, time
20 from mercurial import hg, mdiff, fancyopts
20 from mercurial import hg, mdiff, fancyopts
21
21
22 def help():
22 def help():
23 print """\
23 print """\
24 commands:
24 commands:
25
25
26 init create a new repository in this directory
26 init create a new repository in this directory
27 branch <path> create a branch of <path> in this directory
27 branch <path> create a branch of <path> in this directory
28 merge <path> merge changes from <path> into local repository
28 merge <path> merge changes from <path> into local repository
29 checkout [changeset] checkout the latest or given changeset
29 checkout [changeset] checkout the latest or given changeset
30 status show new, missing, and changed files in working dir
30 status show new, missing, and changed files in working dir
31 add [files...] add the given files in the next commit
31 add [files...] add the given files in the next commit
32 remove [files...] remove the given files in the next commit
32 remove [files...] remove the given files in the next commit
33 addremove add all new files, delete all missing files
33 addremove add all new files, delete all missing files
34 commit commit all changes to the repository
34 commit commit all changes to the repository
35 history show changeset history
35 history show changeset history
36 log <file> show revision history of a single file
36 log <file> show revision history of a single file
37 dump <file> [rev] dump the latest or given revision of a file
37 dump <file> [rev] dump the latest or given revision of a file
38 dumpmanifest [rev] dump the latest or given revision of the manifest
38 dumpmanifest [rev] dump the latest or given revision of the manifest
39 diff [files...] diff working directory (or selected files)
39 diff [files...] diff working directory (or selected files)
40 tags show current changeset tags
40 tags show current changeset tags
41 annotate [files...] show changeset number per file line
41 annotate [files...] show changeset number per file line
42 blame [files...] show commit user per file line
42 blame [files...] show commit user per file line
43 """
43 """
44
44
45 def filterfiles(list, files):
45 def filterfiles(list, files):
46 l = [ x for x in list if x in files ]
46 l = [ x for x in list if x in files ]
47
47
48 for f in files:
48 for f in files:
49 if f[-1] != os.sep: f += os.sep
49 if f[-1] != os.sep: f += os.sep
50 l += [ x for x in list if x.startswith(f) ]
50 l += [ x for x in list if x.startswith(f) ]
51 return l
51 return l
52
52
53 def diff(files = None, node1 = None, node2 = None):
53 def diff(files = None, node1 = None, node2 = None):
54 def date(c):
54 def date(c):
55 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
55 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
56
56
57 if node2:
57 if node2:
58 change = repo.changelog.read(node2)
58 change = repo.changelog.read(node2)
59 mmap2 = repo.manifest.read(change[0])
59 mmap2 = repo.manifest.read(change[0])
60 (c, a, d) = repo.diffrevs(node1, node2)
60 (c, a, d) = repo.diffrevs(node1, node2)
61 def read(f): return repo.file(f).read(mmap2[f])
61 def read(f): return repo.file(f).read(mmap2[f])
62 date2 = date(change)
62 date2 = date(change)
63 else:
63 else:
64 date2 = time.asctime()
64 date2 = time.asctime()
65 if not node1:
65 if not node1:
66 node1 = repo.current
66 node1 = repo.current
67 (c, a, d) = repo.diffdir(repo.root, node1)
67 (c, a, d) = repo.diffdir(repo.root, node1)
68 def read(f): return file(os.path.join(repo.root, f)).read()
68 def read(f): return file(os.path.join(repo.root, f)).read()
69
69
70 change = repo.changelog.read(node1)
70 change = repo.changelog.read(node1)
71 mmap = repo.manifest.read(change[0])
71 mmap = repo.manifest.read(change[0])
72 date1 = date(change)
72 date1 = date(change)
73
73
74 if files:
74 if files:
75 (c, a, d) = map(lambda x: filterfiles(x, files), (c, a, d))
75 (c, a, d) = map(lambda x: filterfiles(x, files), (c, a, d))
76
76
77 for f in c:
77 for f in c:
78 to = repo.file(f).read(mmap[f])
78 to = repo.file(f).read(mmap[f])
79 tn = read(f)
79 tn = read(f)
80 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
80 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
81 for f in a:
81 for f in a:
82 to = ""
82 to = ""
83 tn = read(f)
83 tn = read(f)
84 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
84 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
85 for f in d:
85 for f in d:
86 to = repo.file(f).read(mmap[f])
86 to = repo.file(f).read(mmap[f])
87 tn = ""
87 tn = ""
88 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
88 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
89
89
90 options = {}
90 options = {}
91 opts = [('v', 'verbose', None, 'verbose'),
91 opts = [('v', 'verbose', None, 'verbose'),
92 ('d', 'debug', None, 'debug'),
92 ('d', 'debug', None, 'debug'),
93 ('q', 'quiet', None, 'quiet')]
93 ('q', 'quiet', None, 'quiet')]
94
94
95 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
95 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
96 'hg [options] <command> [command options] [files]')
96 'hg [options] <command> [command options] [files]')
97
97
98 try:
98 try:
99 cmd = args[0]
99 cmd = args[0]
100 args = args[1:]
100 args = args[1:]
101 except:
101 except:
102 cmd = ""
102 cmd = ""
103
103
104 ui = hg.ui(options["verbose"], options["debug"], options["quiet"])
104 ui = hg.ui(options["verbose"], options["debug"], options["quiet"])
105
105
106 if cmd == "init":
106 if cmd == "init":
107 repo = hg.repository(ui, ".", create=1)
107 repo = hg.repository(ui, ".", create=1)
108 sys.exit(0)
108 sys.exit(0)
109 elif cmd == "branch" or cmd == "clone":
109 elif cmd == "branch" or cmd == "clone":
110 os.system("cp -al %s/.hg .hg" % args[0])
110 os.system("cp -al %s/.hg .hg" % args[0])
111 sys.exit(0)
111 sys.exit(0)
112 elif cmd == "help":
112 elif cmd == "help":
113 help()
113 help()
114 sys.exit(0)
114 sys.exit(0)
115 else:
115 else:
116 try:
116 try:
117 repo = hg.repository(ui=ui)
117 repo = hg.repository(ui=ui)
118 except IOError:
118 except IOError:
119 ui.warn("Unable to open repository\n")
119 ui.warn("Unable to open repository\n")
120 sys.exit(0)
120 sys.exit(0)
121
121
122 if cmd == "checkout" or cmd == "co":
122 if cmd == "checkout" or cmd == "co":
123 node = repo.changelog.tip()
123 node = repo.changelog.tip()
124 if args:
124 if args:
125 node = repo.lookup(args[0])
125 node = repo.lookup(args[0])
126 repo.checkout(node)
126 repo.checkout(node)
127
127
128 elif cmd == "add":
128 elif cmd == "add":
129 repo.add(args)
129 repo.add(args)
130
130
131 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
131 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
132 repo.remove(args)
132 repo.remove(args)
133
133
134 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
134 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
135 if 1:
135 if 1:
136 if len(args) > 0:
136 if len(args) > 0:
137 repo.commit(repo.current, args)
137 repo.commit(repo.current, args)
138 else:
138 else:
139 repo.commit(repo.current)
139 repo.commit(repo.current)
140
140
141 elif cmd == "import" or cmd == "patch":
141 elif cmd == "import" or cmd == "patch":
142 try:
142 try:
143 import psyco
143 import psyco
144 psyco.full()
144 psyco.full()
145 except:
145 except:
146 pass
146 pass
147
147
148 ioptions = {}
148 ioptions = {}
149 opts = [('p', 'strip', 1, 'path strip'),
149 opts = [('p', 'strip', 1, 'path strip'),
150 ('b', 'base', "", 'base path'),
150 ('b', 'base', "", 'base path'),
151 ('q', 'quiet', "", 'silence diff')
151 ('q', 'quiet', "", 'silence diff')
152 ]
152 ]
153
153
154 args = fancyopts.fancyopts(args, opts, ioptions,
154 args = fancyopts.fancyopts(args, opts, ioptions,
155 'hg import [options] <patch names>')
155 'hg import [options] <patch names>')
156 d = ioptions["base"]
156 d = ioptions["base"]
157 strip = ioptions["strip"]
157 strip = ioptions["strip"]
158 quiet = ioptions["quiet"] and "> /dev/null" or ""
158 quiet = ioptions["quiet"] and "> /dev/null" or ""
159
159
160 for patch in args:
160 for patch in args:
161 ui.status("applying %s\n" % patch)
161 ui.status("applying %s\n" % patch)
162 pf = os.path.join(d, patch)
162 pf = os.path.join(d, patch)
163
163
164 text = ""
164 text = ""
165 for l in file(pf):
165 for l in file(pf):
166 if l[:4] == "--- ": break
166 if l[:4] == "--- ": break
167 text += l
167 text += l
168
168
169 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
169 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
170 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
170 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
171 f.close()
171 f.close()
172
172
173 if files:
173 if files:
174 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
174 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
175 raise "patch failed!"
175 raise "patch failed!"
176 repo.commit(repo.current, files, text)
176 repo.commit(repo.current, files, text)
177
177
178 elif cmd == "status":
178 elif cmd == "status":
179 (c, a, d) = repo.diffdir(repo.root, repo.current)
179 (c, a, d) = repo.diffdir(repo.root, repo.current)
180 for f in c: ui.status("C %s\n" % f)
180 for f in c: ui.status("C %s\n" % f)
181 for f in a: ui.status("? %s\n" % f)
181 for f in a: ui.status("? %s\n" % f)
182 for f in d: ui.status("R %s\n" % f)
182 for f in d: ui.status("R %s\n" % f)
183
183
184 elif cmd == "diff":
184 elif cmd == "diff":
185 revs = []
185 revs = []
186
186
187 if args:
187 if args:
188 doptions = {}
188 doptions = {}
189 opts = [('r', 'revision', [], 'revision')]
189 opts = [('r', 'revision', [], 'revision')]
190 args = fancyopts.fancyopts(args, opts, doptions,
190 args = fancyopts.fancyopts(args, opts, doptions,
191 'hg diff [options] [files]')
191 'hg diff [options] [files]')
192 revs = map(lambda x: repo.lookup(x), doptions['revision'])
192 revs = map(lambda x: repo.lookup(x), doptions['revision'])
193
193
194 if len(revs) > 2:
194 if len(revs) > 2:
195 self.ui.warn("too many revisions to diff\n")
195 self.ui.warn("too many revisions to diff\n")
196 sys.exit(1)
196 sys.exit(1)
197
197
198 if os.getcwd() != repo.root:
198 if os.getcwd() != repo.root:
199 relpath = os.getcwd()[len(repo.root) + 1: ]
199 relpath = os.getcwd()[len(repo.root) + 1: ]
200 if not args: args = [ relpath ]
200 if not args: args = [ relpath ]
201 else: args = [ os.path.join(relpath, x) for x in args ]
201 else: args = [ os.path.join(relpath, x) for x in args ]
202
202
203 diff(args, *revs)
203 diff(args, *revs)
204
204
205 elif cmd == "annotate":
205 elif cmd == "annotate":
206 aoptions = {}
206 aoptions = {}
207 opts = [('r', 'revision', '', 'revision')]
207 opts = [('r', 'revision', '', 'revision')]
208 args = fancyopts.fancyopts(args, opts, aoptions,
208 args = fancyopts.fancyopts(args, opts, aoptions,
209 'hg annotate [-r id] [files]')
209 'hg annotate [-r id] [files]')
210 if args:
210 if args:
211 node = repo.current
211 node = repo.current
212 if aoptions['revision']:
212 if aoptions['revision']:
213 node = repo.changelog.lookup(aoptions['revision'])
213 node = repo.changelog.lookup(aoptions['revision'])
214 change = repo.changelog.read(node)
214 change = repo.changelog.read(node)
215 mmap = repo.manifest.read(change[0])
215 mmap = repo.manifest.read(change[0])
216 for f in args:
216 for f in args:
217 for n, l in repo.file(f).annotate(mmap[f]):
217 for n, l in repo.file(f).annotate(mmap[f]):
218 sys.stdout.write("% 6s:%s"%(n, l))
218 sys.stdout.write("% 6s:%s"%(n, l))
219
219
220 elif cmd == "blame":
220 elif cmd == "blame":
221 aoptions = {}
221 aoptions = {}
222 opts = [('r', 'revision', '', 'revision')]
222 opts = [('r', 'revision', '', 'revision')]
223 args = fancyopts.fancyopts(args, opts, aoptions,
223 args = fancyopts.fancyopts(args, opts, aoptions,
224 'hg blame [-r id] [files]')
224 'hg blame [-r id] [files]')
225 if args:
225 if args:
226 bcache = {}
226 bcache = {}
227 node = repo.current
227 node = repo.current
228 if aoptions['revision']:
228 if aoptions['revision']:
229 node = repo.changelog.lookup(aoptions['revision'])
229 node = repo.changelog.lookup(aoptions['revision'])
230 change = repo.changelog.read(node)
230 change = repo.changelog.read(node)
231 mmap = repo.manifest.read(change[0])
231 mmap = repo.manifest.read(change[0])
232 for f in args:
232 for f in args:
233 for n, l in repo.file(f).annotate(mmap[f]):
233 for n, l in repo.file(f).annotate(mmap[f]):
234 try:
234 try:
235 name = bcache[n]
235 name = bcache[n]
236 except KeyError:
236 except KeyError:
237 cl = repo.changelog.read(repo.changelog.node(n))
237 cl = repo.changelog.read(repo.changelog.node(n))
238 name = cl[1]
238 name = cl[1]
239 f = name.find('@')
239 f = name.find('@')
240 if f >= 0:
240 if f >= 0:
241 name = name[:f]
241 name = name[:f]
242 bcache[n] = name
242 bcache[n] = name
243 sys.stdout.write("% 10s:%s"%(name, l))
243 sys.stdout.write("% 10s:%s"%(name, l))
244
244
245 elif cmd == "export":
245 elif cmd == "export":
246 node = repo.lookup(args[0])
246 node = repo.lookup(args[0])
247 prev, other = repo.changelog.parents(node)
247 prev, other = repo.changelog.parents(node)
248 change = repo.changelog.read(node)
248 change = repo.changelog.read(node)
249 print "# HG changeset patch"
249 print "# HG changeset patch"
250 print "# User %s" % change[1]
250 print "# User %s" % change[1]
251 print "# Node ID %s" % hg.hex(node)
251 print "# Node ID %s" % hg.hex(node)
252 print "# Parent %s" % hg.hex(prev)
252 print "# Parent %s" % hg.hex(prev)
253 print
253 print
254 if other != hg.nullid:
254 if other != hg.nullid:
255 print "# Parent %s" % hg.hex(other)
255 print "# Parent %s" % hg.hex(other)
256 print change[4]
256 print change[4]
257
257
258 diff(None, prev, node)
258 diff(None, prev, node)
259
259
260 elif cmd == "debugchangegroup":
260 elif cmd == "debugchangegroup":
261 newer = repo.newer(map(repo.lookup, args))
261 newer = repo.newer(map(repo.lookup, args))
262 for chunk in repo.changegroup(newer):
262 for chunk in repo.changegroup(newer):
263 sys.stdout.write(chunk)
263 sys.stdout.write(chunk)
264
264
265 elif cmd == "debugaddchangegroup":
265 elif cmd == "debugaddchangegroup":
266 data = sys.stdin.read()
266 data = sys.stdin.read()
267 repo.addchangegroup(data)
267 repo.addchangegroup(data)
268
268
269 elif cmd == "addremove":
269 elif cmd == "addremove":
270 (c, a, d) = repo.diffdir(repo.root, repo.current)
270 (c, a, d) = repo.diffdir(repo.root, repo.current)
271 repo.add(a)
271 repo.add(a)
272 repo.remove(d)
272 repo.remove(d)
273
273
274 elif cmd == "history":
274 elif cmd == "history":
275 for i in range(repo.changelog.count()):
275 for i in range(repo.changelog.count()):
276 n = repo.changelog.node(i)
276 n = repo.changelog.node(i)
277 changes = repo.changelog.read(n)
277 changes = repo.changelog.read(n)
278 (p1, p2) = repo.changelog.parents(n)
278 (p1, p2) = repo.changelog.parents(n)
279 (h, h1, h2) = map(hg.hex, (n, p1, p2))
279 (h, h1, h2) = map(hg.hex, (n, p1, p2))
280 (i1, i2) = map(repo.changelog.rev, (p1, p2))
280 (i1, i2) = map(repo.changelog.rev, (p1, p2))
281 print "rev: %4d:%s" % (i, h)
281 print "rev: %4d:%s" % (i, h)
282 print "parents: %4d:%s" % (i1, h1)
282 print "parents: %4d:%s" % (i1, h1)
283 if i2: print " %4d:%s" % (i2, h2)
283 if i2: print " %4d:%s" % (i2, h2)
284 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
284 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
285 hg.hex(changes[0]))
285 hg.hex(changes[0]))
286 print "user:", changes[1]
286 print "user:", changes[1]
287 print "date:", time.asctime(
287 print "date:", time.asctime(
288 time.localtime(float(changes[2].split(' ')[0])))
288 time.localtime(float(changes[2].split(' ')[0])))
289 print "files:", " ".join(changes[3])
289 print "files:", " ".join(changes[3])
290 print "description:"
290 print "description:"
291 print changes[4]
291 print changes[4]
292
292
293 elif cmd == "tip":
293 elif cmd == "tip":
294 n = repo.changelog.tip()
294 n = repo.changelog.tip()
295 t = repo.changelog.rev(n)
295 t = repo.changelog.rev(n)
296 ui.status("%d:%s\n" % (t, hg.hex(n)))
296 ui.status("%d:%s\n" % (t, hg.hex(n)))
297
297
298 elif cmd == "log":
298 elif cmd == "log":
299 if args:
299 if args:
300 r = repo.file(args[0])
300 r = repo.file(args[0])
301 for i in range(r.count()):
301 for i in range(r.count()):
302 n = r.node(i)
302 n = r.node(i)
303 (p1, p2) = r.parents(n)
303 (p1, p2) = r.parents(n)
304 (h, h1, h2) = map(hg.hex, (n, p1, p2))
304 (h, h1, h2) = map(hg.hex, (n, p1, p2))
305 (i1, i2) = map(r.rev, (p1, p2))
305 (i1, i2) = map(r.rev, (p1, p2))
306 cr = r.linkrev(n)
306 cr = r.linkrev(n)
307 cn = hg.hex(repo.changelog.node(cr))
307 cn = hg.hex(repo.changelog.node(cr))
308 print "rev: %4d:%s" % (i, h)
308 print "rev: %4d:%s" % (i, h)
309 print "changeset: %4d:%s" % (cr, cn)
309 print "changeset: %4d:%s" % (cr, cn)
310 print "parents: %4d:%s" % (i1, h1)
310 print "parents: %4d:%s" % (i1, h1)
311 if i2: print " %4d:%s" % (i2, h2)
311 if i2: print " %4d:%s" % (i2, h2)
312 else:
312 else:
313 print "missing filename"
313 print "missing filename"
314
314
315 elif cmd == "dump":
315 elif cmd == "dump":
316 if args:
316 if args:
317 r = repo.file(args[0])
317 r = repo.file(args[0])
318 n = r.tip()
318 n = r.tip()
319 if len(args) > 1: n = r.lookup(args[1])
319 if len(args) > 1: n = r.lookup(args[1])
320 sys.stdout.write(r.read(n))
320 sys.stdout.write(r.read(n))
321 else:
321 else:
322 print "missing filename"
322 print "missing filename"
323
323
324 elif cmd == "dumpmanifest":
324 elif cmd == "dumpmanifest":
325 n = repo.manifest.tip()
325 n = repo.manifest.tip()
326 if len(args) > 0:
326 if len(args) > 0:
327 n = repo.manifest.lookup(args[0])
327 n = repo.manifest.lookup(args[0])
328 m = repo.manifest.read(n)
328 m = repo.manifest.read(n)
329 files = m.keys()
329 files = m.keys()
330 files.sort()
330 files.sort()
331
331
332 for f in files:
332 for f in files:
333 print hg.hex(m[f]), f
333 print hg.hex(m[f]), f
334
334
335 elif cmd == "debughash":
335 elif cmd == "debughash":
336 f = repo.file(args[0])
336 f = repo.file(args[0])
337 print f.encodepath(args[0])
337 print f.encodepath(args[0])
338
338
339 elif cmd == "debugindex":
339 elif cmd == "debugindex":
340 if ".hg" not in args[0]:
340 if ".hg" not in args[0]:
341 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
341 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
342
342
343 r = hg.revlog(open, args[0], "")
343 r = hg.revlog(open, args[0], "")
344 print " rev offset length base linkrev"+\
344 print " rev offset length base linkrev"+\
345 " p1 p2 nodeid"
345 " p1 p2 nodeid"
346 for i in range(r.count()):
346 for i in range(r.count()):
347 e = r.index[i]
347 e = r.index[i]
348 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
348 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
349 i, e[0], e[1], e[2], e[3],
349 i, e[0], e[1], e[2], e[3],
350 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
350 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
351
351
352 elif cmd == "debugindexdot":
352 elif cmd == "debugindexdot":
353 if ".hg" not in args[0]:
353 if ".hg" not in args[0]:
354 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
354 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
355
355
356 r = hg.revlog(open, args[0], "")
356 r = hg.revlog(open, args[0], "")
357 print "digraph G {"
357 print "digraph G {"
358 for i in range(r.count()):
358 for i in range(r.count()):
359 e = r.index[i]
359 e = r.index[i]
360 print "\t%d -> %d" % (r.rev(e[4]), i)
360 print "\t%d -> %d" % (r.rev(e[4]), i)
361 if e[5] != hg.nullid:
361 if e[5] != hg.nullid:
362 print "\t%d -> %d" % (r.rev(e[5]), i)
362 print "\t%d -> %d" % (r.rev(e[5]), i)
363 print "}"
363 print "}"
364
364
365 elif cmd == "merge":
365 elif cmd == "merge":
366 if args:
366 if args:
367 other = hg.repository(ui, args[0])
367 other = hg.repository(ui, args[0])
368 ui.status("requesting changegroup\n")
368 ui.status("requesting changegroup\n")
369 cg = repo.getchangegroup(other)
369 cg = repo.getchangegroup(other)
370 repo.addchangegroup(cg)
370 repo.addchangegroup(cg)
371 else:
371 else:
372 print "missing source repository"
372 print "missing source repository"
373
373
374 elif cmd == "tags":
374 elif cmd == "tags":
375 repo.lookup(0) # prime the cache
375 repo.lookup(0) # prime the cache
376 i = repo.tags.items()
376 i = repo.tags.items()
377 i.sort()
377 i.sort()
378 for k, n in i:
378 for k, n in i:
379 try:
379 try:
380 r = repo.changelog.rev(n)
380 r = repo.changelog.rev(n)
381 except KeyError:
381 except KeyError:
382 r = "?"
382 r = "?"
383 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
383 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
384
384
385 elif cmd == "debugoldmerge":
385 elif cmd == "debugoldmerge":
386 if args:
386 if args:
387 other = hg.repository(ui, args[0])
387 other = hg.repository(ui, args[0])
388 repo.merge(other)
388 repo.merge(other)
389 else:
389 else:
390 print "missing source repository"
390 print "missing source repository"
391
391
392 elif cmd == "verify":
392 elif cmd == "verify":
393 filelinkrevs = {}
393 filelinkrevs = {}
394 filenodes = {}
394 filenodes = {}
395 manifestchangeset = {}
395 manifestchangeset = {}
396 changesets = revisions = files = 0
396 changesets = revisions = files = 0
397 errors = 0
397 errors = 0
398
398
399 ui.status("checking changesets\n")
399 ui.status("checking changesets\n")
400 for i in range(repo.changelog.count()):
400 for i in range(repo.changelog.count()):
401 changesets += 1
401 changesets += 1
402 n = repo.changelog.node(i)
402 n = repo.changelog.node(i)
403 for p in repo.changelog.parents(n):
403 for p in repo.changelog.parents(n):
404 if p not in repo.changelog.nodemap:
404 if p not in repo.changelog.nodemap:
405 ui.warn("changeset %s has unknown parent %s\n" %
405 ui.warn("changeset %s has unknown parent %s\n" %
406 (hg.short(n), hg.short(p)))
406 (hg.short(n), hg.short(p)))
407 errors += 1
407 errors += 1
408 try:
408 try:
409 changes = repo.changelog.read(n)
409 changes = repo.changelog.read(n)
410 except Error, inst:
410 except Error, inst:
411 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
411 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
412 errors += 1
412 errors += 1
413
413
414 manifestchangeset[changes[0]] = n
414 manifestchangeset[changes[0]] = n
415 for f in changes[3]:
415 for f in changes[3]:
416 revisions += 1
416 revisions += 1
417 filelinkrevs.setdefault(f, []).append(i)
417 filelinkrevs.setdefault(f, []).append(i)
418
418
419 ui.status("checking manifests\n")
419 ui.status("checking manifests\n")
420 for i in range(repo.manifest.count()):
420 for i in range(repo.manifest.count()):
421 n = repo.manifest.node(i)
421 n = repo.manifest.node(i)
422 for p in repo.manifest.parents(n):
422 for p in repo.manifest.parents(n):
423 if p not in repo.manifest.nodemap:
423 if p not in repo.manifest.nodemap:
424 ui.warn("manifest %s has unknown parent %s\n" %
424 ui.warn("manifest %s has unknown parent %s\n" %
425 (hg.short(n), hg.short(p)))
425 (hg.short(n), hg.short(p)))
426 errors += 1
426 errors += 1
427 ca = repo.changelog.node(repo.manifest.linkrev(n))
427 ca = repo.changelog.node(repo.manifest.linkrev(n))
428 cc = manifestchangeset[n]
428 cc = manifestchangeset[n]
429 if ca != cc:
429 if ca != cc:
430 ui.warn("manifest %s points to %s, not %s\n" %
430 ui.warn("manifest %s points to %s, not %s\n" %
431 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
431 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
432 errors += 1
432 errors += 1
433
433
434 try:
434 try:
435 m = repo.manifest.read(n)
435 m = repo.manifest.read(n)
436 except Error, inst:
436 except Exception, inst:
437 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
437 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
438 errors += 1
438 errors += 1
439
439
440 for f, fn in m.items():
440 for f, fn in m.items():
441 filenodes.setdefault(f, {})[fn] = 1
441 filenodes.setdefault(f, {})[fn] = 1
442
442
443 ui.status("crosschecking files in changesets and manifests\n")
443 ui.status("crosschecking files in changesets and manifests\n")
444 for f in filenodes:
444 for f in filenodes:
445 if f not in filelinkrevs:
445 if f not in filelinkrevs:
446 ui.warn("file %s in manifest but not in changesets\n" % f)
446 ui.warn("file %s in manifest but not in changesets\n" % f)
447 errors += 1
447 errors += 1
448
448
449 for f in filelinkrevs:
449 for f in filelinkrevs:
450 if f not in filenodes:
450 if f not in filenodes:
451 ui.warn("file %s in changeset but not in manifest" % f)
451 ui.warn("file %s in changeset but not in manifest" % f)
452 errors += 1
452 errors += 1
453
453
454 ui.status("checking files\n")
454 ui.status("checking files\n")
455 for f in filenodes:
455 for f in filenodes:
456 files += 1
456 files += 1
457 fl = repo.file(f)
457 fl = repo.file(f)
458 nodes = { hg.nullid: 1 }
458 nodes = { hg.nullid: 1 }
459 for i in range(fl.count()):
459 for i in range(fl.count()):
460 n = fl.node(i)
460 n = fl.node(i)
461
461
462 if n not in filenodes[f]:
462 if n not in filenodes[f]:
463 ui.warn("%s:%s not in manifests\n" % (f, hg.short(n)))
463 ui.warn("%s:%s not in manifests\n" % (f, hg.short(n)))
464 errors += 1
464 errors += 1
465 else:
465 else:
466 del filenodes[f][n]
466 del filenodes[f][n]
467
467
468 flr = fl.linkrev(n)
468 flr = fl.linkrev(n)
469 if flr not in filelinkrevs[f]:
469 if flr not in filelinkrevs[f]:
470 ui.warn("%s:%s points to unexpected changeset rev %d\n"
470 ui.warn("%s:%s points to unexpected changeset rev %d\n"
471 % (f, hg.short(n), fl.linkrev(n)))
471 % (f, hg.short(n), fl.linkrev(n)))
472 errors += 1
472 errors += 1
473 else:
473 else:
474 filelinkrevs[f].remove(flr)
474 filelinkrevs[f].remove(flr)
475
475
476 # verify contents
476 # verify contents
477 try:
477 try:
478 t = fl.read(n)
478 t = fl.read(n)
479 except Error, inst:
479 except Error, inst:
480 ui.warn("unpacking file %s %s: %s\n" % (f, short(n), inst))
480 ui.warn("unpacking file %s %s: %s\n" % (f, short(n), inst))
481 errors += 1
481 errors += 1
482
482
483 # verify parents
483 # verify parents
484 (p1, p2) = fl.parents(n)
484 (p1, p2) = fl.parents(n)
485 if p1 not in nodes:
485 if p1 not in nodes:
486 ui.warn("file %s:%s unknown parent 1 %s" %
486 ui.warn("file %s:%s unknown parent 1 %s" %
487 (f, hg.short(n), hg.short(p1)))
487 (f, hg.short(n), hg.short(p1)))
488 errors += 1
488 errors += 1
489 if p2 not in nodes:
489 if p2 not in nodes:
490 ui.warn("file %s:%s unknown parent 2 %s" %
490 ui.warn("file %s:%s unknown parent 2 %s" %
491 (f, hg.short(n), hg.short(p1)))
491 (f, hg.short(n), hg.short(p1)))
492 errors += 1
492 errors += 1
493 nodes[n] = 1
493 nodes[n] = 1
494
494
495 # cross-check
495 # cross-check
496 for flr in filelinkrevs[f]:
496 for flr in filelinkrevs[f]:
497 ui.warn("changeset rev %d not in %s\n" % (flr, f))
497 ui.warn("changeset rev %d not in %s\n" % (flr, f))
498 errors += 1
498 errors += 1
499
499
500 for node in filenodes[f]:
500 for node in filenodes[f]:
501 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
501 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
502 errors += 1
502 errors += 1
503
503
504 ui.status("%d files, %d changesets, %d total revisions\n" %
504 ui.status("%d files, %d changesets, %d total revisions\n" %
505 (files, changesets, revisions))
505 (files, changesets, revisions))
506
506
507 if errors:
507 if errors:
508 ui.warn("%d integrity errors encountered!\n")
508 ui.warn("%d integrity errors encountered!\n" % errors)
509 sys.exit(1)
509 sys.exit(1)
510
510
511 else:
511 else:
512 print "unknown command\n"
512 print "unknown command\n"
513 help()
513 help()
514 sys.exit(1)
514 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now