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