##// END OF EJS Templates
hack so that debugindex takes filenames
mpm@selenic.com -
r91:1c212bbb default
parent child Browse files
Show More
@@ -1,498 +1,501 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]:
341 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
342
340 r = hg.revlog(open, args[0], "")
343 r = hg.revlog(open, args[0], "")
341 print " rev offset length base linkrev"+\
344 print " rev offset length base linkrev"+\
342 " p1 p2 nodeid"
345 " p1 p2 nodeid"
343 for i in range(r.count()):
346 for i in range(r.count()):
344 e = r.index[i]
347 e = r.index[i]
345 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
348 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
346 i, e[0], e[1], e[2], e[3],
349 i, e[0], e[1], e[2], e[3],
347 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]))
348
351
349 elif cmd == "merge":
352 elif cmd == "merge":
350 if args:
353 if args:
351 other = hg.repository(ui, args[0])
354 other = hg.repository(ui, args[0])
352 ui.status("requesting changegroup\n")
355 ui.status("requesting changegroup\n")
353 cg = repo.getchangegroup(other)
356 cg = repo.getchangegroup(other)
354 repo.addchangegroup(cg)
357 repo.addchangegroup(cg)
355 else:
358 else:
356 print "missing source repository"
359 print "missing source repository"
357
360
358 elif cmd == "tags":
361 elif cmd == "tags":
359 repo.lookup(0) # prime the cache
362 repo.lookup(0) # prime the cache
360 i = repo.tags.items()
363 i = repo.tags.items()
361 i.sort()
364 i.sort()
362 for k, n in i:
365 for k, n in i:
363 try:
366 try:
364 r = repo.changelog.rev(n)
367 r = repo.changelog.rev(n)
365 except KeyError:
368 except KeyError:
366 r = "?"
369 r = "?"
367 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
370 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
368
371
369 elif cmd == "debugoldmerge":
372 elif cmd == "debugoldmerge":
370 if args:
373 if args:
371 other = hg.repository(ui, args[0])
374 other = hg.repository(ui, args[0])
372 repo.merge(other)
375 repo.merge(other)
373 else:
376 else:
374 print "missing source repository"
377 print "missing source repository"
375
378
376 elif cmd == "verify":
379 elif cmd == "verify":
377 filelinkrevs = {}
380 filelinkrevs = {}
378 filenodes = {}
381 filenodes = {}
379 manifestchangeset = {}
382 manifestchangeset = {}
380 changesets = revisions = files = 0
383 changesets = revisions = files = 0
381 errors = 0
384 errors = 0
382
385
383 ui.status("checking changesets\n")
386 ui.status("checking changesets\n")
384 for i in range(repo.changelog.count()):
387 for i in range(repo.changelog.count()):
385 changesets += 1
388 changesets += 1
386 n = repo.changelog.node(i)
389 n = repo.changelog.node(i)
387 for p in repo.changelog.parents(n):
390 for p in repo.changelog.parents(n):
388 if p not in repo.changelog.nodemap:
391 if p not in repo.changelog.nodemap:
389 ui.warn("changeset %s has unknown parent %s\n" %
392 ui.warn("changeset %s has unknown parent %s\n" %
390 (hg.short(n), hg.short(p)))
393 (hg.short(n), hg.short(p)))
391 errors += 1
394 errors += 1
392 try:
395 try:
393 changes = repo.changelog.read(n)
396 changes = repo.changelog.read(n)
394 except Error, inst:
397 except Error, inst:
395 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
398 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
396 errors += 1
399 errors += 1
397
400
398 manifestchangeset[changes[0]] = n
401 manifestchangeset[changes[0]] = n
399 for f in changes[3]:
402 for f in changes[3]:
400 revisions += 1
403 revisions += 1
401 filelinkrevs.setdefault(f, []).append(i)
404 filelinkrevs.setdefault(f, []).append(i)
402
405
403 ui.status("checking manifests\n")
406 ui.status("checking manifests\n")
404 for i in range(repo.manifest.count()):
407 for i in range(repo.manifest.count()):
405 n = repo.manifest.node(i)
408 n = repo.manifest.node(i)
406 for p in repo.manifest.parents(n):
409 for p in repo.manifest.parents(n):
407 if p not in repo.manifest.nodemap:
410 if p not in repo.manifest.nodemap:
408 ui.warn("manifest %s has unknown parent %s\n" %
411 ui.warn("manifest %s has unknown parent %s\n" %
409 (hg.short(n), hg.short(p)))
412 (hg.short(n), hg.short(p)))
410 errors += 1
413 errors += 1
411 ca = repo.changelog.node(repo.manifest.linkrev(n))
414 ca = repo.changelog.node(repo.manifest.linkrev(n))
412 cc = manifestchangeset[n]
415 cc = manifestchangeset[n]
413 if ca != cc:
416 if ca != cc:
414 ui.warn("manifest %s points to %s, not %s\n" %
417 ui.warn("manifest %s points to %s, not %s\n" %
415 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
418 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
416 errors += 1
419 errors += 1
417
420
418 try:
421 try:
419 m = repo.manifest.read(n)
422 m = repo.manifest.read(n)
420 except Error, inst:
423 except Error, inst:
421 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
424 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
422 errors += 1
425 errors += 1
423
426
424 for f, fn in m.items():
427 for f, fn in m.items():
425 filenodes.setdefault(f, {})[fn] = 1
428 filenodes.setdefault(f, {})[fn] = 1
426
429
427 ui.status("crosschecking files in changesets and manifests\n")
430 ui.status("crosschecking files in changesets and manifests\n")
428 for f in filenodes:
431 for f in filenodes:
429 if f not in filelinkrevs:
432 if f not in filelinkrevs:
430 ui.warn("file %s in manifest but not in changesets\n" % f)
433 ui.warn("file %s in manifest but not in changesets\n" % f)
431 errors += 1
434 errors += 1
432
435
433 for f in filelinkrevs:
436 for f in filelinkrevs:
434 if f not in filenodes:
437 if f not in filenodes:
435 ui.warn("file %s in changeset but not in manifest" % f)
438 ui.warn("file %s in changeset but not in manifest" % f)
436 errors += 1
439 errors += 1
437
440
438 ui.status("checking files\n")
441 ui.status("checking files\n")
439 for f in filenodes:
442 for f in filenodes:
440 files += 1
443 files += 1
441 fl = repo.file(f)
444 fl = repo.file(f)
442 nodes = { hg.nullid: 1 }
445 nodes = { hg.nullid: 1 }
443 for i in range(fl.count()):
446 for i in range(fl.count()):
444 n = fl.node(i)
447 n = fl.node(i)
445
448
446 if n not in filenodes[f]:
449 if n not in filenodes[f]:
447 ui.warn("%s:%s not in manifests\n" % (f, hg.short(n)))
450 ui.warn("%s:%s not in manifests\n" % (f, hg.short(n)))
448 errors += 1
451 errors += 1
449 else:
452 else:
450 del filenodes[f][n]
453 del filenodes[f][n]
451
454
452 flr = fl.linkrev(n)
455 flr = fl.linkrev(n)
453 if flr not in filelinkrevs[f]:
456 if flr not in filelinkrevs[f]:
454 ui.warn("%s:%s points to unexpected changeset rev %d\n"
457 ui.warn("%s:%s points to unexpected changeset rev %d\n"
455 % (f, hg.short(n), fl.linkrev(n)))
458 % (f, hg.short(n), fl.linkrev(n)))
456 errors += 1
459 errors += 1
457 else:
460 else:
458 filelinkrevs[f].remove(flr)
461 filelinkrevs[f].remove(flr)
459
462
460 # verify contents
463 # verify contents
461 try:
464 try:
462 t = fl.read(n)
465 t = fl.read(n)
463 except Error, inst:
466 except Error, inst:
464 ui.warn("unpacking file %s %s: %s\n" % (f, short(n), inst))
467 ui.warn("unpacking file %s %s: %s\n" % (f, short(n), inst))
465 errors += 1
468 errors += 1
466
469
467 # verify parents
470 # verify parents
468 (p1, p2) = fl.parents(n)
471 (p1, p2) = fl.parents(n)
469 if p1 not in nodes:
472 if p1 not in nodes:
470 ui.warn("file %s:%s unknown parent 1 %s" %
473 ui.warn("file %s:%s unknown parent 1 %s" %
471 (f, hg.short(n), hg.short(p1)))
474 (f, hg.short(n), hg.short(p1)))
472 errors += 1
475 errors += 1
473 if p2 not in nodes:
476 if p2 not in nodes:
474 ui.warn("file %s:%s unknown parent 2 %s" %
477 ui.warn("file %s:%s unknown parent 2 %s" %
475 (f, hg.short(n), hg.short(p1)))
478 (f, hg.short(n), hg.short(p1)))
476 errors += 1
479 errors += 1
477 nodes[n] = 1
480 nodes[n] = 1
478
481
479 # cross-check
482 # cross-check
480 for flr in filelinkrevs[f]:
483 for flr in filelinkrevs[f]:
481 ui.warn("changeset rev %d not in %s\n" % (flr, f))
484 ui.warn("changeset rev %d not in %s\n" % (flr, f))
482 errors += 1
485 errors += 1
483
486
484 for node in filenodes[f]:
487 for node in filenodes[f]:
485 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
488 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
486 errors += 1
489 errors += 1
487
490
488 ui.status("%d files, %d changesets, %d total revisions\n" %
491 ui.status("%d files, %d changesets, %d total revisions\n" %
489 (files, changesets, revisions))
492 (files, changesets, revisions))
490
493
491 if errors:
494 if errors:
492 ui.warn("%d integrity errors encountered!\n")
495 ui.warn("%d integrity errors encountered!\n")
493 sys.exit(1)
496 sys.exit(1)
494
497
495 else:
498 else:
496 print "unknown command\n"
499 print "unknown command\n"
497 help()
500 help()
498 sys.exit(1)
501 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now