##// END OF EJS Templates
hg history: don't print file list without -v switch
mpm@selenic.com -
r123:b93cc016 default
parent child Browse files
Show More
@@ -1,547 +1,547 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 = filterfiles(c, files)
75 c = filterfiles(c, files)
76 d = filterfiles(d, files)
76 d = filterfiles(d, files)
77
77
78 for f in c:
78 for f in c:
79 to = repo.file(f).read(mmap[f])
79 to = repo.file(f).read(mmap[f])
80 tn = read(f)
80 tn = read(f)
81 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
81 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
82 for f in d:
82 for f in d:
83 to = repo.file(f).read(mmap[f])
83 to = repo.file(f).read(mmap[f])
84 tn = ""
84 tn = ""
85 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
85 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
86
86
87 options = {}
87 options = {}
88 opts = [('v', 'verbose', None, 'verbose'),
88 opts = [('v', 'verbose', None, 'verbose'),
89 ('d', 'debug', None, 'debug'),
89 ('d', 'debug', None, 'debug'),
90 ('q', 'quiet', None, 'quiet'),
90 ('q', 'quiet', None, 'quiet'),
91 ('y', 'noninteractive', None, 'run non-interactively'),
91 ('y', 'noninteractive', None, 'run non-interactively'),
92 ]
92 ]
93
93
94 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
94 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
95 'hg [options] <command> [command options] [files]')
95 'hg [options] <command> [command options] [files]')
96
96
97 try:
97 try:
98 cmd = args[0]
98 cmd = args[0]
99 args = args[1:]
99 args = args[1:]
100 except:
100 except:
101 cmd = ""
101 cmd = ""
102
102
103 ui = hg.ui(options["verbose"], options["debug"], options["quiet"],
103 ui = hg.ui(options["verbose"], options["debug"], options["quiet"],
104 not options["noninteractive"])
104 not options["noninteractive"])
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 relpath = None
122 relpath = None
123 if os.getcwd() != repo.root:
123 if os.getcwd() != repo.root:
124 relpath = os.getcwd()[len(repo.root) + 1: ]
124 relpath = os.getcwd()[len(repo.root) + 1: ]
125
125
126 if cmd == "checkout" or cmd == "co":
126 if cmd == "checkout" or cmd == "co":
127 node = repo.changelog.tip()
127 node = repo.changelog.tip()
128 if args:
128 if args:
129 node = repo.lookup(args[0])
129 node = repo.lookup(args[0])
130 repo.checkout(node)
130 repo.checkout(node)
131
131
132 elif cmd == "add":
132 elif cmd == "add":
133 repo.add(args)
133 repo.add(args)
134
134
135 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
135 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
136 repo.remove(args)
136 repo.remove(args)
137
137
138 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
138 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
139 if 1:
139 if 1:
140 if len(args) > 0:
140 if len(args) > 0:
141 repo.commit(repo.current, args)
141 repo.commit(repo.current, args)
142 else:
142 else:
143 repo.commit(repo.current)
143 repo.commit(repo.current)
144
144
145 elif cmd == "import" or cmd == "patch":
145 elif cmd == "import" or cmd == "patch":
146 try:
146 try:
147 import psyco
147 import psyco
148 psyco.full()
148 psyco.full()
149 except:
149 except:
150 pass
150 pass
151
151
152 ioptions = {}
152 ioptions = {}
153 opts = [('p', 'strip', 1, 'path strip'),
153 opts = [('p', 'strip', 1, 'path strip'),
154 ('b', 'base', "", 'base path'),
154 ('b', 'base', "", 'base path'),
155 ('q', 'quiet', "", 'silence diff')
155 ('q', 'quiet', "", 'silence diff')
156 ]
156 ]
157
157
158 args = fancyopts.fancyopts(args, opts, ioptions,
158 args = fancyopts.fancyopts(args, opts, ioptions,
159 'hg import [options] <patch names>')
159 'hg import [options] <patch names>')
160 d = ioptions["base"]
160 d = ioptions["base"]
161 strip = ioptions["strip"]
161 strip = ioptions["strip"]
162 quiet = ioptions["quiet"] and "> /dev/null" or ""
162 quiet = ioptions["quiet"] and "> /dev/null" or ""
163
163
164 for patch in args:
164 for patch in args:
165 ui.status("applying %s\n" % patch)
165 ui.status("applying %s\n" % patch)
166 pf = os.path.join(d, patch)
166 pf = os.path.join(d, patch)
167
167
168 text = ""
168 text = ""
169 for l in file(pf):
169 for l in file(pf):
170 if l[:4] == "--- ": break
170 if l[:4] == "--- ": break
171 text += l
171 text += l
172
172
173 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
173 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
174 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
174 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
175 f.close()
175 f.close()
176
176
177 if files:
177 if files:
178 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
178 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
179 raise "patch failed!"
179 raise "patch failed!"
180 repo.commit(repo.current, files, text)
180 repo.commit(repo.current, files, text)
181
181
182 elif cmd == "status":
182 elif cmd == "status":
183 (c, a, d) = repo.diffdir(repo.root, repo.current)
183 (c, a, d) = repo.diffdir(repo.root, repo.current)
184 if relpath:
184 if relpath:
185 (c, a, d) = map(lambda x: filterfiles(x, [ relpath ]), (c, a, d))
185 (c, a, d) = map(lambda x: filterfiles(x, [ relpath ]), (c, a, d))
186
186
187 for f in c: print "C", f
187 for f in c: print "C", f
188 for f in a: print "?", f
188 for f in a: print "?", f
189 for f in d: print "R", f
189 for f in d: print "R", f
190
190
191 elif cmd == "diff":
191 elif cmd == "diff":
192 revs = []
192 revs = []
193
193
194 if args:
194 if args:
195 doptions = {}
195 doptions = {}
196 opts = [('r', 'revision', [], 'revision')]
196 opts = [('r', 'revision', [], 'revision')]
197 args = fancyopts.fancyopts(args, opts, doptions,
197 args = fancyopts.fancyopts(args, opts, doptions,
198 'hg diff [options] [files]')
198 'hg diff [options] [files]')
199 revs = map(lambda x: repo.lookup(x), doptions['revision'])
199 revs = map(lambda x: repo.lookup(x), doptions['revision'])
200
200
201 if len(revs) > 2:
201 if len(revs) > 2:
202 self.ui.warn("too many revisions to diff\n")
202 self.ui.warn("too many revisions to diff\n")
203 sys.exit(1)
203 sys.exit(1)
204
204
205 if relpath:
205 if relpath:
206 if not args: args = [ relpath ]
206 if not args: args = [ relpath ]
207 else: args = [ os.path.join(relpath, x) for x in args ]
207 else: args = [ os.path.join(relpath, x) for x in args ]
208
208
209 diff(args, *revs)
209 diff(args, *revs)
210
210
211 elif cmd == "annotate":
211 elif cmd == "annotate":
212 aoptions = {}
212 aoptions = {}
213 opts = [('r', 'revision', '', 'revision')]
213 opts = [('r', 'revision', '', 'revision')]
214 args = fancyopts.fancyopts(args, opts, aoptions,
214 args = fancyopts.fancyopts(args, opts, aoptions,
215 'hg annotate [-r id] [files]')
215 'hg annotate [-r id] [files]')
216
216
217 if args:
217 if args:
218 if relpath: args = [ os.path.join(relpath, x) for x in args ]
218 if relpath: args = [ os.path.join(relpath, x) for x in args ]
219
219
220 node = repo.current
220 node = repo.current
221 if aoptions['revision']:
221 if aoptions['revision']:
222 node = repo.changelog.lookup(aoptions['revision'])
222 node = repo.changelog.lookup(aoptions['revision'])
223 change = repo.changelog.read(node)
223 change = repo.changelog.read(node)
224 mmap = repo.manifest.read(change[0])
224 mmap = repo.manifest.read(change[0])
225 for f in args:
225 for f in args:
226 for n, l in repo.file(f).annotate(mmap[f]):
226 for n, l in repo.file(f).annotate(mmap[f]):
227 sys.stdout.write("% 6s:%s"%(n, l))
227 sys.stdout.write("% 6s:%s"%(n, l))
228
228
229 elif cmd == "blame":
229 elif cmd == "blame":
230 aoptions = {}
230 aoptions = {}
231 opts = [('r', 'revision', '', 'revision')]
231 opts = [('r', 'revision', '', 'revision')]
232 args = fancyopts.fancyopts(args, opts, aoptions,
232 args = fancyopts.fancyopts(args, opts, aoptions,
233 'hg blame [-r id] [files]')
233 'hg blame [-r id] [files]')
234 if args:
234 if args:
235 bcache = {}
235 bcache = {}
236 node = repo.current
236 node = repo.current
237 if aoptions['revision']:
237 if aoptions['revision']:
238 node = repo.changelog.lookup(aoptions['revision'])
238 node = repo.changelog.lookup(aoptions['revision'])
239 change = repo.changelog.read(node)
239 change = repo.changelog.read(node)
240 mmap = repo.manifest.read(change[0])
240 mmap = repo.manifest.read(change[0])
241 for f in args:
241 for f in args:
242 for n, l in repo.file(f).annotate(mmap[f]):
242 for n, l in repo.file(f).annotate(mmap[f]):
243 try:
243 try:
244 name = bcache[n]
244 name = bcache[n]
245 except KeyError:
245 except KeyError:
246 cl = repo.changelog.read(repo.changelog.node(n))
246 cl = repo.changelog.read(repo.changelog.node(n))
247 name = cl[1]
247 name = cl[1]
248 f = name.find('@')
248 f = name.find('@')
249 if f >= 0:
249 if f >= 0:
250 name = name[:f]
250 name = name[:f]
251 bcache[n] = name
251 bcache[n] = name
252 sys.stdout.write("% 10s:%s"%(name, l))
252 sys.stdout.write("% 10s:%s"%(name, l))
253
253
254 elif cmd == "export":
254 elif cmd == "export":
255 node = repo.lookup(args[0])
255 node = repo.lookup(args[0])
256 prev, other = repo.changelog.parents(node)
256 prev, other = repo.changelog.parents(node)
257 change = repo.changelog.read(node)
257 change = repo.changelog.read(node)
258 print "# HG changeset patch"
258 print "# HG changeset patch"
259 print "# User %s" % change[1]
259 print "# User %s" % change[1]
260 print "# Node ID %s" % hg.hex(node)
260 print "# Node ID %s" % hg.hex(node)
261 print "# Parent %s" % hg.hex(prev)
261 print "# Parent %s" % hg.hex(prev)
262 print
262 print
263 if other != hg.nullid:
263 if other != hg.nullid:
264 print "# Parent %s" % hg.hex(other)
264 print "# Parent %s" % hg.hex(other)
265 print change[4]
265 print change[4]
266
266
267 diff(None, prev, node)
267 diff(None, prev, node)
268
268
269 elif cmd == "debugchangegroup":
269 elif cmd == "debugchangegroup":
270 newer = repo.newer(map(repo.lookup, args))
270 newer = repo.newer(map(repo.lookup, args))
271 for chunk in repo.changegroup(newer):
271 for chunk in repo.changegroup(newer):
272 sys.stdout.write(chunk)
272 sys.stdout.write(chunk)
273
273
274 elif cmd == "debugaddchangegroup":
274 elif cmd == "debugaddchangegroup":
275 data = sys.stdin.read()
275 data = sys.stdin.read()
276 repo.addchangegroup(data)
276 repo.addchangegroup(data)
277
277
278 elif cmd == "addremove":
278 elif cmd == "addremove":
279 (c, a, d) = repo.diffdir(repo.root, repo.current)
279 (c, a, d) = repo.diffdir(repo.root, repo.current)
280 repo.add(a)
280 repo.add(a)
281 repo.remove(d)
281 repo.remove(d)
282
282
283 elif cmd == "history":
283 elif cmd == "history":
284 for i in range(repo.changelog.count()):
284 for i in range(repo.changelog.count()):
285 n = repo.changelog.node(i)
285 n = repo.changelog.node(i)
286 changes = repo.changelog.read(n)
286 changes = repo.changelog.read(n)
287 (p1, p2) = repo.changelog.parents(n)
287 (p1, p2) = repo.changelog.parents(n)
288 (h, h1, h2) = map(hg.hex, (n, p1, p2))
288 (h, h1, h2) = map(hg.hex, (n, p1, p2))
289 (i1, i2) = map(repo.changelog.rev, (p1, p2))
289 (i1, i2) = map(repo.changelog.rev, (p1, p2))
290 print "rev: %4d:%s" % (i, h)
290 print "rev: %4d:%s" % (i, h)
291 print "parents: %4d:%s" % (i1, h1)
291 print "parents: %4d:%s" % (i1, h1)
292 if i2: print " %4d:%s" % (i2, h2)
292 if i2: print " %4d:%s" % (i2, h2)
293 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
293 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
294 hg.hex(changes[0]))
294 hg.hex(changes[0]))
295 print "user:", changes[1]
295 print "user:", changes[1]
296 print "date:", time.asctime(
296 print "date:", time.asctime(
297 time.localtime(float(changes[2].split(' ')[0])))
297 time.localtime(float(changes[2].split(' ')[0])))
298 print "files:", " ".join(changes[3])
298 if ui.verbose: print "files:", " ".join(changes[3])
299 print "description:"
299 print "description:"
300 print changes[4]
300 print changes[4]
301
301
302 elif cmd == "tip":
302 elif cmd == "tip":
303 n = repo.changelog.tip()
303 n = repo.changelog.tip()
304 t = repo.changelog.rev(n)
304 t = repo.changelog.rev(n)
305 ui.status("%d:%s\n" % (t, hg.hex(n)))
305 ui.status("%d:%s\n" % (t, hg.hex(n)))
306
306
307 elif cmd == "log":
307 elif cmd == "log":
308
308
309 if len(args) == 1:
309 if len(args) == 1:
310 if relpath:
310 if relpath:
311 args[0] = os.path.join(relpath, args[0])
311 args[0] = os.path.join(relpath, args[0])
312
312
313 r = repo.file(args[0])
313 r = repo.file(args[0])
314 for i in range(r.count()):
314 for i in range(r.count()):
315 n = r.node(i)
315 n = r.node(i)
316 (p1, p2) = r.parents(n)
316 (p1, p2) = r.parents(n)
317 (h, h1, h2) = map(hg.hex, (n, p1, p2))
317 (h, h1, h2) = map(hg.hex, (n, p1, p2))
318 (i1, i2) = map(r.rev, (p1, p2))
318 (i1, i2) = map(r.rev, (p1, p2))
319 cr = r.linkrev(n)
319 cr = r.linkrev(n)
320 cn = hg.hex(repo.changelog.node(cr))
320 cn = hg.hex(repo.changelog.node(cr))
321 print "rev: %4d:%s" % (i, h)
321 print "rev: %4d:%s" % (i, h)
322 print "changeset: %4d:%s" % (cr, cn)
322 print "changeset: %4d:%s" % (cr, cn)
323 print "parents: %4d:%s" % (i1, h1)
323 print "parents: %4d:%s" % (i1, h1)
324 if i2: print " %4d:%s" % (i2, h2)
324 if i2: print " %4d:%s" % (i2, h2)
325 changes = repo.changelog.read(repo.changelog.node(cr))
325 changes = repo.changelog.read(repo.changelog.node(cr))
326 print "user: %s" % changes[1]
326 print "user: %s" % changes[1]
327 print "date: %s" % time.asctime(
327 print "date: %s" % time.asctime(
328 time.localtime(float(changes[2].split(' ')[0])))
328 time.localtime(float(changes[2].split(' ')[0])))
329 print "description:"
329 print "description:"
330 print changes[4]
330 print changes[4]
331 print
331 print
332 elif len(args) > 1:
332 elif len(args) > 1:
333 print "too many args"
333 print "too many args"
334 else:
334 else:
335 print "missing filename"
335 print "missing filename"
336
336
337 elif cmd == "dump":
337 elif cmd == "dump":
338 if args:
338 if args:
339 r = repo.file(args[0])
339 r = repo.file(args[0])
340 n = r.tip()
340 n = r.tip()
341 if len(args) > 1: n = r.lookup(args[1])
341 if len(args) > 1: n = r.lookup(args[1])
342 sys.stdout.write(r.read(n))
342 sys.stdout.write(r.read(n))
343 else:
343 else:
344 print "missing filename"
344 print "missing filename"
345
345
346 elif cmd == "dumpmanifest":
346 elif cmd == "dumpmanifest":
347 n = repo.manifest.tip()
347 n = repo.manifest.tip()
348 if len(args) > 0:
348 if len(args) > 0:
349 n = repo.manifest.lookup(args[0])
349 n = repo.manifest.lookup(args[0])
350 m = repo.manifest.read(n)
350 m = repo.manifest.read(n)
351 files = m.keys()
351 files = m.keys()
352 files.sort()
352 files.sort()
353
353
354 for f in files:
354 for f in files:
355 print hg.hex(m[f]), f
355 print hg.hex(m[f]), f
356
356
357 elif cmd == "debugprompt":
357 elif cmd == "debugprompt":
358 print ui.prompt(args[0], args[1], args[2])
358 print ui.prompt(args[0], args[1], args[2])
359
359
360 elif cmd == "debughash":
360 elif cmd == "debughash":
361 f = repo.file(args[0])
361 f = repo.file(args[0])
362 print f.encodepath(args[0])
362 print f.encodepath(args[0])
363
363
364 elif cmd == "debugindex":
364 elif cmd == "debugindex":
365 if ".hg" not in args[0]:
365 if ".hg" not in args[0]:
366 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
366 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
367
367
368 r = hg.revlog(open, args[0], "")
368 r = hg.revlog(open, args[0], "")
369 print " rev offset length base linkrev"+\
369 print " rev offset length base linkrev"+\
370 " p1 p2 nodeid"
370 " p1 p2 nodeid"
371 for i in range(r.count()):
371 for i in range(r.count()):
372 e = r.index[i]
372 e = r.index[i]
373 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
373 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
374 i, e[0], e[1], e[2], e[3],
374 i, e[0], e[1], e[2], e[3],
375 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
375 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
376
376
377 elif cmd == "debugindexdot":
377 elif cmd == "debugindexdot":
378 if ".hg" not in args[0]:
378 if ".hg" not in args[0]:
379 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
379 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
380
380
381 r = hg.revlog(open, args[0], "")
381 r = hg.revlog(open, args[0], "")
382 print "digraph G {"
382 print "digraph G {"
383 for i in range(r.count()):
383 for i in range(r.count()):
384 e = r.index[i]
384 e = r.index[i]
385 print "\t%d -> %d" % (r.rev(e[4]), i)
385 print "\t%d -> %d" % (r.rev(e[4]), i)
386 if e[5] != hg.nullid:
386 if e[5] != hg.nullid:
387 print "\t%d -> %d" % (r.rev(e[5]), i)
387 print "\t%d -> %d" % (r.rev(e[5]), i)
388 print "}"
388 print "}"
389
389
390 elif cmd == "merge":
390 elif cmd == "merge":
391 if args:
391 if args:
392 other = hg.repository(ui, args[0])
392 other = hg.repository(ui, args[0])
393 ui.status("requesting changegroup\n")
393 ui.status("requesting changegroup\n")
394 cg = repo.getchangegroup(other)
394 cg = repo.getchangegroup(other)
395 repo.addchangegroup(cg)
395 repo.addchangegroup(cg)
396 else:
396 else:
397 print "missing source repository"
397 print "missing source repository"
398
398
399 elif cmd == "tags":
399 elif cmd == "tags":
400 repo.lookup(0) # prime the cache
400 repo.lookup(0) # prime the cache
401 i = repo.tags.items()
401 i = repo.tags.items()
402 i.sort()
402 i.sort()
403 for k, n in i:
403 for k, n in i:
404 try:
404 try:
405 r = repo.changelog.rev(n)
405 r = repo.changelog.rev(n)
406 except KeyError:
406 except KeyError:
407 r = "?"
407 r = "?"
408 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
408 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
409
409
410 elif cmd == "debugoldmerge":
410 elif cmd == "debugoldmerge":
411 if args:
411 if args:
412 other = hg.repository(ui, args[0])
412 other = hg.repository(ui, args[0])
413 repo.merge(other)
413 repo.merge(other)
414 else:
414 else:
415 print "missing source repository"
415 print "missing source repository"
416
416
417 elif cmd == "verify":
417 elif cmd == "verify":
418 filelinkrevs = {}
418 filelinkrevs = {}
419 filenodes = {}
419 filenodes = {}
420 manifestchangeset = {}
420 manifestchangeset = {}
421 changesets = revisions = files = 0
421 changesets = revisions = files = 0
422 errors = 0
422 errors = 0
423
423
424 ui.status("checking changesets\n")
424 ui.status("checking changesets\n")
425 for i in range(repo.changelog.count()):
425 for i in range(repo.changelog.count()):
426 changesets += 1
426 changesets += 1
427 n = repo.changelog.node(i)
427 n = repo.changelog.node(i)
428 for p in repo.changelog.parents(n):
428 for p in repo.changelog.parents(n):
429 if p not in repo.changelog.nodemap:
429 if p not in repo.changelog.nodemap:
430 ui.warn("changeset %s has unknown parent %s\n" %
430 ui.warn("changeset %s has unknown parent %s\n" %
431 (hg.short(n), hg.short(p)))
431 (hg.short(n), hg.short(p)))
432 errors += 1
432 errors += 1
433 try:
433 try:
434 changes = repo.changelog.read(n)
434 changes = repo.changelog.read(n)
435 except Error, inst:
435 except Error, inst:
436 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
436 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
437 errors += 1
437 errors += 1
438
438
439 manifestchangeset[changes[0]] = n
439 manifestchangeset[changes[0]] = n
440 for f in changes[3]:
440 for f in changes[3]:
441 revisions += 1
441 revisions += 1
442 filelinkrevs.setdefault(f, []).append(i)
442 filelinkrevs.setdefault(f, []).append(i)
443
443
444 ui.status("checking manifests\n")
444 ui.status("checking manifests\n")
445 for i in range(repo.manifest.count()):
445 for i in range(repo.manifest.count()):
446 n = repo.manifest.node(i)
446 n = repo.manifest.node(i)
447 for p in repo.manifest.parents(n):
447 for p in repo.manifest.parents(n):
448 if p not in repo.manifest.nodemap:
448 if p not in repo.manifest.nodemap:
449 ui.warn("manifest %s has unknown parent %s\n" %
449 ui.warn("manifest %s has unknown parent %s\n" %
450 (hg.short(n), hg.short(p)))
450 (hg.short(n), hg.short(p)))
451 errors += 1
451 errors += 1
452 ca = repo.changelog.node(repo.manifest.linkrev(n))
452 ca = repo.changelog.node(repo.manifest.linkrev(n))
453 cc = manifestchangeset[n]
453 cc = manifestchangeset[n]
454 if ca != cc:
454 if ca != cc:
455 ui.warn("manifest %s points to %s, not %s\n" %
455 ui.warn("manifest %s points to %s, not %s\n" %
456 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
456 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
457 errors += 1
457 errors += 1
458
458
459 try:
459 try:
460 delta = mdiff.patchtext(repo.manifest.delta(n))
460 delta = mdiff.patchtext(repo.manifest.delta(n))
461 except KeyboardInterrupt:
461 except KeyboardInterrupt:
462 print "aborted"
462 print "aborted"
463 sys.exit(0)
463 sys.exit(0)
464 except Exception, inst:
464 except Exception, inst:
465 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
465 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
466 errors += 1
466 errors += 1
467
467
468 ff = [ l.split('\0') for l in delta.splitlines() ]
468 ff = [ l.split('\0') for l in delta.splitlines() ]
469 for f, fn in ff:
469 for f, fn in ff:
470 filenodes.setdefault(f, {})[hg.bin(fn)] = 1
470 filenodes.setdefault(f, {})[hg.bin(fn)] = 1
471
471
472 ui.status("crosschecking files in changesets and manifests\n")
472 ui.status("crosschecking files in changesets and manifests\n")
473 for f in filenodes:
473 for f in filenodes:
474 if f not in filelinkrevs:
474 if f not in filelinkrevs:
475 ui.warn("file %s in manifest but not in changesets\n" % f)
475 ui.warn("file %s in manifest but not in changesets\n" % f)
476 errors += 1
476 errors += 1
477
477
478 for f in filelinkrevs:
478 for f in filelinkrevs:
479 if f not in filenodes:
479 if f not in filenodes:
480 ui.warn("file %s in changeset but not in manifest\n" % f)
480 ui.warn("file %s in changeset but not in manifest\n" % f)
481 errors += 1
481 errors += 1
482
482
483 ui.status("checking files\n")
483 ui.status("checking files\n")
484 ff = filenodes.keys()
484 ff = filenodes.keys()
485 ff.sort()
485 ff.sort()
486 for f in ff:
486 for f in ff:
487 if f == "/dev/null": continue
487 if f == "/dev/null": continue
488 files += 1
488 files += 1
489 fl = repo.file(f)
489 fl = repo.file(f)
490 nodes = { hg.nullid: 1 }
490 nodes = { hg.nullid: 1 }
491 for i in range(fl.count()):
491 for i in range(fl.count()):
492 n = fl.node(i)
492 n = fl.node(i)
493
493
494 if n not in filenodes[f]:
494 if n not in filenodes[f]:
495 ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n)))
495 ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n)))
496 print len(filenodes[f].keys()), fl.count(), f
496 print len(filenodes[f].keys()), fl.count(), f
497 errors += 1
497 errors += 1
498 else:
498 else:
499 del filenodes[f][n]
499 del filenodes[f][n]
500
500
501 flr = fl.linkrev(n)
501 flr = fl.linkrev(n)
502 if flr not in filelinkrevs[f]:
502 if flr not in filelinkrevs[f]:
503 ui.warn("%s:%s points to unexpected changeset rev %d\n"
503 ui.warn("%s:%s points to unexpected changeset rev %d\n"
504 % (f, hg.short(n), fl.linkrev(n)))
504 % (f, hg.short(n), fl.linkrev(n)))
505 errors += 1
505 errors += 1
506 else:
506 else:
507 filelinkrevs[f].remove(flr)
507 filelinkrevs[f].remove(flr)
508
508
509 # verify contents
509 # verify contents
510 try:
510 try:
511 t = fl.read(n)
511 t = fl.read(n)
512 except Error, inst:
512 except Error, inst:
513 ui.warn("unpacking file %s %s: %s\n" % (f, short(n), inst))
513 ui.warn("unpacking file %s %s: %s\n" % (f, short(n), inst))
514 errors += 1
514 errors += 1
515
515
516 # verify parents
516 # verify parents
517 (p1, p2) = fl.parents(n)
517 (p1, p2) = fl.parents(n)
518 if p1 not in nodes:
518 if p1 not in nodes:
519 ui.warn("file %s:%s unknown parent 1 %s" %
519 ui.warn("file %s:%s unknown parent 1 %s" %
520 (f, hg.short(n), hg.short(p1)))
520 (f, hg.short(n), hg.short(p1)))
521 errors += 1
521 errors += 1
522 if p2 not in nodes:
522 if p2 not in nodes:
523 ui.warn("file %s:%s unknown parent 2 %s" %
523 ui.warn("file %s:%s unknown parent 2 %s" %
524 (f, hg.short(n), hg.short(p1)))
524 (f, hg.short(n), hg.short(p1)))
525 errors += 1
525 errors += 1
526 nodes[n] = 1
526 nodes[n] = 1
527
527
528 # cross-check
528 # cross-check
529 for flr in filelinkrevs[f]:
529 for flr in filelinkrevs[f]:
530 ui.warn("changeset rev %d not in %s\n" % (flr, f))
530 ui.warn("changeset rev %d not in %s\n" % (flr, f))
531 errors += 1
531 errors += 1
532
532
533 for node in filenodes[f]:
533 for node in filenodes[f]:
534 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
534 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
535 errors += 1
535 errors += 1
536
536
537 ui.status("%d files, %d changesets, %d total revisions\n" %
537 ui.status("%d files, %d changesets, %d total revisions\n" %
538 (files, changesets, revisions))
538 (files, changesets, revisions))
539
539
540 if errors:
540 if errors:
541 ui.warn("%d integrity errors encountered!\n" % errors)
541 ui.warn("%d integrity errors encountered!\n" % errors)
542 sys.exit(1)
542 sys.exit(1)
543
543
544 else:
544 else:
545 print "unknown command\n"
545 print "unknown command\n"
546 help()
546 help()
547 sys.exit(1)
547 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now