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