##// END OF EJS Templates
added hg identify|id (based on a patch from Andrew Thompson)...
Thomas Arendsen Hein -
r339:a76fc9c4 default
parent child Browse files
Show More
@@ -1,724 +1,745 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 import os, re, sys, signal
8 import os, re, sys, signal
9 import fancyopts, ui, hg
9 import fancyopts, ui, hg
10 from demandload import *
10 from demandload import *
11 demandload(globals(), "mdiff time hgweb traceback random signal")
11 demandload(globals(), "mdiff time hgweb traceback random signal")
12
12
13 class UnknownCommand(Exception): pass
13 class UnknownCommand(Exception): pass
14
14
15 def filterfiles(filters, files):
15 def filterfiles(filters, files):
16 l = [ x for x in files if x in filters ]
16 l = [ x for x in files if x in filters ]
17
17
18 for t in filters:
18 for t in filters:
19 if t and t[-1] != os.sep: t += os.sep
19 if t and t[-1] != os.sep: t += os.sep
20 l += [ x for x in files if x.startswith(t) ]
20 l += [ x for x in files if x.startswith(t) ]
21 return l
21 return l
22
22
23 def relfilter(repo, files):
23 def relfilter(repo, files):
24 if os.getcwd() != repo.root:
24 if os.getcwd() != repo.root:
25 p = os.getcwd()[len(repo.root) + 1: ]
25 p = os.getcwd()[len(repo.root) + 1: ]
26 return filterfiles([p], files)
26 return filterfiles([p], files)
27 return files
27 return files
28
28
29 def relpath(repo, args):
29 def relpath(repo, args):
30 if os.getcwd() != repo.root:
30 if os.getcwd() != repo.root:
31 p = os.getcwd()[len(repo.root) + 1: ]
31 p = os.getcwd()[len(repo.root) + 1: ]
32 return [ os.path.normpath(os.path.join(p, x)) for x in args ]
32 return [ os.path.normpath(os.path.join(p, x)) for x in args ]
33 return args
33 return args
34
34
35 def dodiff(repo, path, files = None, node1 = None, node2 = None):
35 def dodiff(repo, path, files = None, node1 = None, node2 = None):
36 def date(c):
36 def date(c):
37 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
37 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
38
38
39 if node2:
39 if node2:
40 change = repo.changelog.read(node2)
40 change = repo.changelog.read(node2)
41 mmap2 = repo.manifest.read(change[0])
41 mmap2 = repo.manifest.read(change[0])
42 (c, a, d) = repo.diffrevs(node1, node2)
42 (c, a, d) = repo.diffrevs(node1, node2)
43 def read(f): return repo.file(f).read(mmap2[f])
43 def read(f): return repo.file(f).read(mmap2[f])
44 date2 = date(change)
44 date2 = date(change)
45 else:
45 else:
46 date2 = time.asctime()
46 date2 = time.asctime()
47 (c, a, d, u) = repo.diffdir(path, node1)
47 (c, a, d, u) = repo.diffdir(path, node1)
48 if not node1:
48 if not node1:
49 node1 = repo.dirstate.parents()[0]
49 node1 = repo.dirstate.parents()[0]
50 def read(f): return file(os.path.join(repo.root, f)).read()
50 def read(f): return file(os.path.join(repo.root, f)).read()
51
51
52 change = repo.changelog.read(node1)
52 change = repo.changelog.read(node1)
53 mmap = repo.manifest.read(change[0])
53 mmap = repo.manifest.read(change[0])
54 date1 = date(change)
54 date1 = date(change)
55
55
56 if files:
56 if files:
57 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
57 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
58
58
59 for f in c:
59 for f in c:
60 to = None
60 to = None
61 if f in mmap:
61 if f in mmap:
62 to = repo.file(f).read(mmap[f])
62 to = repo.file(f).read(mmap[f])
63 tn = read(f)
63 tn = read(f)
64 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
64 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
65 for f in a:
65 for f in a:
66 to = None
66 to = None
67 tn = read(f)
67 tn = read(f)
68 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
68 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
69 for f in d:
69 for f in d:
70 to = repo.file(f).read(mmap[f])
70 to = repo.file(f).read(mmap[f])
71 tn = None
71 tn = None
72 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
72 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
73
73
74 def show_changeset(ui, repo, rev=0, changenode=None, filelog=None):
74 def show_changeset(ui, repo, rev=0, changenode=None, filelog=None):
75 """show a single changeset or file revision"""
75 """show a single changeset or file revision"""
76 changelog = repo.changelog
76 changelog = repo.changelog
77 if filelog:
77 if filelog:
78 log = filelog
78 log = filelog
79 filerev = rev
79 filerev = rev
80 node = filenode = filelog.node(filerev)
80 node = filenode = filelog.node(filerev)
81 changerev = filelog.linkrev(filenode)
81 changerev = filelog.linkrev(filenode)
82 changenode = changenode or changelog.node(changerev)
82 changenode = changenode or changelog.node(changerev)
83 else:
83 else:
84 changerev = rev
84 changerev = rev
85 log = changelog
85 log = changelog
86 if changenode is None:
86 if changenode is None:
87 changenode = changelog.node(changerev)
87 changenode = changelog.node(changerev)
88 elif not changerev:
88 elif not changerev:
89 rev = changerev = changelog.rev(changenode)
89 rev = changerev = changelog.rev(changenode)
90 node = changenode
90 node = changenode
91
91
92 if ui.quiet:
92 if ui.quiet:
93 ui.write("%d:%s\n" % (rev, hg.hex(node)))
93 ui.write("%d:%s\n" % (rev, hg.hex(node)))
94 return
94 return
95
95
96 changes = changelog.read(changenode)
96 changes = changelog.read(changenode)
97 description = changes[4].strip().splitlines()
97 description = changes[4].strip().splitlines()
98
98
99 parents = [(log.rev(parent), hg.hex(parent))
99 parents = [(log.rev(parent), hg.hex(parent))
100 for parent in log.parents(node)
100 for parent in log.parents(node)
101 if ui.debugflag or parent != hg.nullid]
101 if ui.debugflag or parent != hg.nullid]
102 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
102 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
103 parents = []
103 parents = []
104
104
105 if filelog:
105 if filelog:
106 ui.write("revision: %d:%s\n" % (filerev, hg.hex(filenode)))
106 ui.write("revision: %d:%s\n" % (filerev, hg.hex(filenode)))
107 for parent in parents:
107 for parent in parents:
108 ui.write("parent: %d:%s\n" % parent)
108 ui.write("parent: %d:%s\n" % parent)
109 ui.status("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
109 ui.status("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
110 else:
110 else:
111 ui.write("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
111 ui.write("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
112 for parent in parents:
112 for parent in parents:
113 ui.write("parent: %d:%s\n" % parent)
113 ui.write("parent: %d:%s\n" % parent)
114 ui.note("manifest: %d:%s\n" % (repo.manifest.rev(changes[0]),
114 ui.note("manifest: %d:%s\n" % (repo.manifest.rev(changes[0]),
115 hg.hex(changes[0])))
115 hg.hex(changes[0])))
116 ui.status("user: %s\n" % changes[1])
116 ui.status("user: %s\n" % changes[1])
117 ui.status("date: %s\n" % time.asctime(
117 ui.status("date: %s\n" % time.asctime(
118 time.localtime(float(changes[2].split(' ')[0]))))
118 time.localtime(float(changes[2].split(' ')[0]))))
119 ui.note("files: %s\n" % " ".join(changes[3]))
119 ui.note("files: %s\n" % " ".join(changes[3]))
120 if description:
120 if description:
121 if ui.verbose:
121 if ui.verbose:
122 ui.status("description:\n")
122 ui.status("description:\n")
123 ui.status(changes[4].strip())
123 ui.status(changes[4].strip())
124 ui.status("\n")
124 ui.status("\n")
125 else:
125 else:
126 ui.status("summary: %s\n" % description[0])
126 ui.status("summary: %s\n" % description[0])
127 ui.status("\n")
127 ui.status("\n")
128
128
129 def tags_load(repo):
130 repo.lookup(0) # prime the cache
131 i = repo.tags.items()
132 n = []
133 for e in i:
134 try:
135 l = repo.changelog.rev(e[1])
136 except KeyError:
137 l = -2
138 n.append((l, e))
139 return n
140
129 def help(ui, cmd=None):
141 def help(ui, cmd=None):
130 '''show help for a given command or all commands'''
142 '''show help for a given command or all commands'''
131 if cmd:
143 if cmd:
132 try:
144 try:
133 i = find(cmd)
145 i = find(cmd)
134 ui.write("%s\n\n" % i[2])
146 ui.write("%s\n\n" % i[2])
135
147
136 if i[1]:
148 if i[1]:
137 for s, l, d, c in i[1]:
149 for s, l, d, c in i[1]:
138 opt=' '
150 opt=' '
139 if s: opt = opt + '-' + s + ' '
151 if s: opt = opt + '-' + s + ' '
140 if l: opt = opt + '--' + l + ' '
152 if l: opt = opt + '--' + l + ' '
141 if d: opt = opt + '(' + str(d) + ')'
153 if d: opt = opt + '(' + str(d) + ')'
142 ui.write(opt, "\n")
154 ui.write(opt, "\n")
143 if c: ui.write(' %s\n' % c)
155 if c: ui.write(' %s\n' % c)
144 ui.write("\n")
156 ui.write("\n")
145
157
146 ui.write(i[0].__doc__, "\n")
158 ui.write(i[0].__doc__, "\n")
147 except UnknownCommand:
159 except UnknownCommand:
148 ui.warn("hg: unknown command %s\n" % cmd)
160 ui.warn("hg: unknown command %s\n" % cmd)
149 sys.exit(0)
161 sys.exit(0)
150 else:
162 else:
151 ui.status('hg commands:\n\n')
163 ui.status('hg commands:\n\n')
152
164
153 h = {}
165 h = {}
154 for e in table.values():
166 for e in table.values():
155 f = e[0]
167 f = e[0]
156 if f.__name__.startswith("debug"): continue
168 if f.__name__.startswith("debug"): continue
157 d = ""
169 d = ""
158 if f.__doc__:
170 if f.__doc__:
159 d = f.__doc__.splitlines(0)[0].rstrip()
171 d = f.__doc__.splitlines(0)[0].rstrip()
160 h[f.__name__] = d
172 h[f.__name__] = d
161
173
162 fns = h.keys()
174 fns = h.keys()
163 fns.sort()
175 fns.sort()
164 m = max(map(len, fns))
176 m = max(map(len, fns))
165 for f in fns:
177 for f in fns:
166 ui.status(' %-*s %s\n' % (m, f, h[f]))
178 ui.status(' %-*s %s\n' % (m, f, h[f]))
167
179
168 # Commands start here, listed alphabetically
180 # Commands start here, listed alphabetically
169
181
170 def add(ui, repo, file, *files):
182 def add(ui, repo, file, *files):
171 '''add the specified files on the next commit'''
183 '''add the specified files on the next commit'''
172 repo.add(relpath(repo, (file,) + files))
184 repo.add(relpath(repo, (file,) + files))
173
185
174 def addremove(ui, repo):
186 def addremove(ui, repo):
175 """add all new files, delete all missing files"""
187 """add all new files, delete all missing files"""
176 (c, a, d, u) = repo.diffdir(repo.root)
188 (c, a, d, u) = repo.diffdir(repo.root)
177 repo.add(u)
189 repo.add(u)
178 repo.remove(d)
190 repo.remove(d)
179
191
180 def annotate(u, repo, file, *files, **ops):
192 def annotate(u, repo, file, *files, **ops):
181 """show changeset information per file line"""
193 """show changeset information per file line"""
182 def getnode(rev):
194 def getnode(rev):
183 return hg.short(repo.changelog.node(rev))
195 return hg.short(repo.changelog.node(rev))
184
196
185 def getname(rev):
197 def getname(rev):
186 try:
198 try:
187 return bcache[rev]
199 return bcache[rev]
188 except KeyError:
200 except KeyError:
189 cl = repo.changelog.read(repo.changelog.node(rev))
201 cl = repo.changelog.read(repo.changelog.node(rev))
190 name = cl[1]
202 name = cl[1]
191 f = name.find('@')
203 f = name.find('@')
192 if f >= 0:
204 if f >= 0:
193 name = name[:f]
205 name = name[:f]
194 bcache[rev] = name
206 bcache[rev] = name
195 return name
207 return name
196
208
197 bcache = {}
209 bcache = {}
198 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
210 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
199 if not ops['user'] and not ops['changeset']:
211 if not ops['user'] and not ops['changeset']:
200 ops['number'] = 1
212 ops['number'] = 1
201
213
202 node = repo.dirstate.parents()[0]
214 node = repo.dirstate.parents()[0]
203 if ops['revision']:
215 if ops['revision']:
204 node = repo.changelog.lookup(ops['revision'])
216 node = repo.changelog.lookup(ops['revision'])
205 change = repo.changelog.read(node)
217 change = repo.changelog.read(node)
206 mmap = repo.manifest.read(change[0])
218 mmap = repo.manifest.read(change[0])
207 maxuserlen = 0
219 maxuserlen = 0
208 maxchangelen = 0
220 maxchangelen = 0
209 for f in relpath(repo, (file,) + files):
221 for f in relpath(repo, (file,) + files):
210 lines = repo.file(f).annotate(mmap[f])
222 lines = repo.file(f).annotate(mmap[f])
211 pieces = []
223 pieces = []
212
224
213 for o, f in opmap:
225 for o, f in opmap:
214 if ops[o]:
226 if ops[o]:
215 l = [ f(n) for n,t in lines ]
227 l = [ f(n) for n,t in lines ]
216 m = max(map(len, l))
228 m = max(map(len, l))
217 pieces.append([ "%*s" % (m, x) for x in l])
229 pieces.append([ "%*s" % (m, x) for x in l])
218
230
219 for p,l in zip(zip(*pieces), lines):
231 for p,l in zip(zip(*pieces), lines):
220 u.write(" ".join(p) + ": " + l[1])
232 u.write(" ".join(p) + ": " + l[1])
221
233
222 def cat(ui, repo, file, rev = []):
234 def cat(ui, repo, file, rev = []):
223 """output the latest or given revision of a file"""
235 """output the latest or given revision of a file"""
224 r = repo.file(relpath(repo, [file])[0])
236 r = repo.file(relpath(repo, [file])[0])
225 n = r.tip()
237 n = r.tip()
226 if rev: n = r.lookup(rev)
238 if rev: n = r.lookup(rev)
227 sys.stdout.write(r.read(n))
239 sys.stdout.write(r.read(n))
228
240
229 def commit(ui, repo, *files, **opts):
241 def commit(ui, repo, *files, **opts):
230 """commit the specified files or all outstanding changes"""
242 """commit the specified files or all outstanding changes"""
231 text = opts['text']
243 text = opts['text']
232 if not text and opts['logfile']:
244 if not text and opts['logfile']:
233 try: text = open(opts['logfile']).read()
245 try: text = open(opts['logfile']).read()
234 except IOError: pass
246 except IOError: pass
235
247
236 repo.commit(relpath(repo, files), text, opts['user'], opts['date'])
248 repo.commit(relpath(repo, files), text, opts['user'], opts['date'])
237
249
238 def debugaddchangegroup(ui, repo):
250 def debugaddchangegroup(ui, repo):
239 data = sys.stdin.read()
251 data = sys.stdin.read()
240 repo.addchangegroup(data)
252 repo.addchangegroup(data)
241
253
242 def debugchangegroup(ui, repo, roots):
254 def debugchangegroup(ui, repo, roots):
243 newer = repo.newer(map(repo.lookup, roots))
255 newer = repo.newer(map(repo.lookup, roots))
244 for chunk in repo.changegroup(newer):
256 for chunk in repo.changegroup(newer):
245 sys.stdout.write(chunk)
257 sys.stdout.write(chunk)
246
258
247 def debugindex(ui, file):
259 def debugindex(ui, file):
248 r = hg.revlog(open, file, "")
260 r = hg.revlog(open, file, "")
249 print " rev offset length base linkrev"+\
261 print " rev offset length base linkrev"+\
250 " p1 p2 nodeid"
262 " p1 p2 nodeid"
251 for i in range(r.count()):
263 for i in range(r.count()):
252 e = r.index[i]
264 e = r.index[i]
253 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
265 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
254 i, e[0], e[1], e[2], e[3],
266 i, e[0], e[1], e[2], e[3],
255 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
267 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
256
268
257 def debugindexdot(ui, file):
269 def debugindexdot(ui, file):
258 r = hg.revlog(open, file, "")
270 r = hg.revlog(open, file, "")
259 print "digraph G {"
271 print "digraph G {"
260 for i in range(r.count()):
272 for i in range(r.count()):
261 e = r.index[i]
273 e = r.index[i]
262 print "\t%d -> %d" % (r.rev(e[4]), i)
274 print "\t%d -> %d" % (r.rev(e[4]), i)
263 if e[5] != hg.nullid:
275 if e[5] != hg.nullid:
264 print "\t%d -> %d" % (r.rev(e[5]), i)
276 print "\t%d -> %d" % (r.rev(e[5]), i)
265 print "}"
277 print "}"
266
278
267 def diff(ui, repo, *files, **opts):
279 def diff(ui, repo, *files, **opts):
268 """diff working directory (or selected files)"""
280 """diff working directory (or selected files)"""
269 revs = []
281 revs = []
270 if opts['rev']:
282 if opts['rev']:
271 revs = map(lambda x: repo.lookup(x), opts['rev'])
283 revs = map(lambda x: repo.lookup(x), opts['rev'])
272
284
273 if len(revs) > 2:
285 if len(revs) > 2:
274 self.ui.warn("too many revisions to diff\n")
286 self.ui.warn("too many revisions to diff\n")
275 sys.exit(1)
287 sys.exit(1)
276
288
277 if files:
289 if files:
278 files = relpath(repo, files)
290 files = relpath(repo, files)
279 else:
291 else:
280 files = relpath(repo, [""])
292 files = relpath(repo, [""])
281
293
282 dodiff(repo, os.getcwd(), files, *revs)
294 dodiff(repo, os.getcwd(), files, *revs)
283
295
284 def export(ui, repo, changeset):
296 def export(ui, repo, changeset):
285 """dump the changeset header and diffs for a revision"""
297 """dump the changeset header and diffs for a revision"""
286 node = repo.lookup(changeset)
298 node = repo.lookup(changeset)
287 prev, other = repo.changelog.parents(node)
299 prev, other = repo.changelog.parents(node)
288 change = repo.changelog.read(node)
300 change = repo.changelog.read(node)
289 print "# HG changeset patch"
301 print "# HG changeset patch"
290 print "# User %s" % change[1]
302 print "# User %s" % change[1]
291 print "# Node ID %s" % hg.hex(node)
303 print "# Node ID %s" % hg.hex(node)
292 print "# Parent %s" % hg.hex(prev)
304 print "# Parent %s" % hg.hex(prev)
293 print
305 print
294 if other != hg.nullid:
306 if other != hg.nullid:
295 print "# Parent %s" % hg.hex(other)
307 print "# Parent %s" % hg.hex(other)
296 print change[4].rstrip()
308 print change[4].rstrip()
297 print
309 print
298
310
299 dodiff(repo, "", None, prev, node)
311 dodiff(repo, "", None, prev, node)
300
312
301 def forget(ui, repo, file, *files):
313 def forget(ui, repo, file, *files):
302 """don't add the specified files on the next commit"""
314 """don't add the specified files on the next commit"""
303 repo.forget(relpath(repo, (file,) + files))
315 repo.forget(relpath(repo, (file,) + files))
304
316
305 def heads(ui, repo):
317 def heads(ui, repo):
306 """show current repository heads"""
318 """show current repository heads"""
307 for n in repo.changelog.heads():
319 for n in repo.changelog.heads():
308 show_changeset(ui, repo, changenode=n)
320 show_changeset(ui, repo, changenode=n)
309
321
310 def history(ui, repo):
322 def history(ui, repo):
311 """show the changelog history"""
323 """show the changelog history"""
312 for i in range(repo.changelog.count() - 1, -1, -1):
324 for i in range(repo.changelog.count() - 1, -1, -1):
313 show_changeset(ui, repo, rev=i)
325 show_changeset(ui, repo, rev=i)
314
326
327 def identify(ui, repo):
328 """print information about the working copy"""
329 (c, a, d, u) = repo.diffdir(repo.root)
330 mflag = (c or a or d or u) and "+" or ""
331 parents = [parent for parent in repo.dirstate.parents()
332 if parent != hg.nullid]
333 tstring = ''
334 if not ui.quiet:
335 taglist = [e[1] for e in tags_load(repo)]
336 tstring = " %s" % ' + '.join([e[0] for e in taglist
337 if e[0] != 'tip' and e[1] in parents])
338
339 hexfunc = ui.verbose and hg.hex or hg.short
340 pstring = '+'.join([hexfunc(parent) for parent in parents])
341 ui.write("%s%s%s\n" % (pstring, mflag, tstring))
342
315 def init(ui, source=None):
343 def init(ui, source=None):
316 """create a new repository or copy an existing one"""
344 """create a new repository or copy an existing one"""
317
345
318 if source:
346 if source:
319 paths = {}
347 paths = {}
320 for name, path in ui.configitems("paths"):
348 for name, path in ui.configitems("paths"):
321 paths[name] = path
349 paths[name] = path
322
350
323 if source in paths: source = paths[source]
351 if source in paths: source = paths[source]
324
352
325 link = 0
353 link = 0
326 if not source.startswith("http://"):
354 if not source.startswith("http://"):
327 d1 = os.stat(os.getcwd()).st_dev
355 d1 = os.stat(os.getcwd()).st_dev
328 d2 = os.stat(source).st_dev
356 d2 = os.stat(source).st_dev
329 if d1 == d2: link = 1
357 if d1 == d2: link = 1
330
358
331 if link:
359 if link:
332 ui.debug("copying by hardlink\n")
360 ui.debug("copying by hardlink\n")
333 os.system("cp -al %s/.hg .hg" % source)
361 os.system("cp -al %s/.hg .hg" % source)
334 try:
362 try:
335 os.remove(".hg/dirstate")
363 os.remove(".hg/dirstate")
336 except: pass
364 except: pass
337
365
338 repo = hg.repository(ui, ".")
366 repo = hg.repository(ui, ".")
339
367
340 else:
368 else:
341 repo = hg.repository(ui, ".", create=1)
369 repo = hg.repository(ui, ".", create=1)
342 other = hg.repository(ui, source)
370 other = hg.repository(ui, source)
343 cg = repo.getchangegroup(other)
371 cg = repo.getchangegroup(other)
344 repo.addchangegroup(cg)
372 repo.addchangegroup(cg)
345 else:
373 else:
346 repo = hg.repository(ui, ".", create=1)
374 repo = hg.repository(ui, ".", create=1)
347
375
348 f = repo.opener("hgrc", "w")
376 f = repo.opener("hgrc", "w")
349 f.write("[paths]\n")
377 f.write("[paths]\n")
350 f.write("default = %s\n" % source)
378 f.write("default = %s\n" % source)
351
379
352 def log(ui, repo, f):
380 def log(ui, repo, f):
353 """show the revision history of a single file"""
381 """show the revision history of a single file"""
354 f = relpath(repo, [f])[0]
382 f = relpath(repo, [f])[0]
355
383
356 r = repo.file(f)
384 r = repo.file(f)
357 for i in range(r.count() - 1, -1, -1):
385 for i in range(r.count() - 1, -1, -1):
358 show_changeset(ui, repo, filelog=r, rev=i)
386 show_changeset(ui, repo, filelog=r, rev=i)
359
387
360 def manifest(ui, repo, rev = []):
388 def manifest(ui, repo, rev = []):
361 """output the latest or given revision of the project manifest"""
389 """output the latest or given revision of the project manifest"""
362 n = repo.manifest.tip()
390 n = repo.manifest.tip()
363 if rev:
391 if rev:
364 n = repo.manifest.lookup(rev)
392 n = repo.manifest.lookup(rev)
365 m = repo.manifest.read(n)
393 m = repo.manifest.read(n)
366 mf = repo.manifest.readflags(n)
394 mf = repo.manifest.readflags(n)
367 files = m.keys()
395 files = m.keys()
368 files.sort()
396 files.sort()
369
397
370 for f in files:
398 for f in files:
371 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f))
399 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f))
372
400
373 def parents(ui, repo, node = None):
401 def parents(ui, repo, node = None):
374 '''show the parents of the current working dir'''
402 '''show the parents of the current working dir'''
375 if node:
403 if node:
376 p = repo.changelog.parents(repo.lookup(hg.bin(node)))
404 p = repo.changelog.parents(repo.lookup(hg.bin(node)))
377 else:
405 else:
378 p = repo.dirstate.parents()
406 p = repo.dirstate.parents()
379
407
380 for n in p:
408 for n in p:
381 if n != hg.nullid:
409 if n != hg.nullid:
382 show_changeset(ui, repo, changenode=n)
410 show_changeset(ui, repo, changenode=n)
383
411
384 def patch(ui, repo, patch1, *patches, **opts):
412 def patch(ui, repo, patch1, *patches, **opts):
385 """import an ordered set of patches"""
413 """import an ordered set of patches"""
386 try:
414 try:
387 import psyco
415 import psyco
388 psyco.full()
416 psyco.full()
389 except:
417 except:
390 pass
418 pass
391
419
392 patches = (patch1,) + patches
420 patches = (patch1,) + patches
393
421
394 d = opts["base"]
422 d = opts["base"]
395 strip = opts["strip"]
423 strip = opts["strip"]
396 quiet = opts["quiet"] and "> /dev/null" or ""
424 quiet = opts["quiet"] and "> /dev/null" or ""
397
425
398 for patch in patches:
426 for patch in patches:
399 ui.status("applying %s\n" % patch)
427 ui.status("applying %s\n" % patch)
400 pf = os.path.join(d, patch)
428 pf = os.path.join(d, patch)
401
429
402 text = ""
430 text = ""
403 for l in file(pf):
431 for l in file(pf):
404 if l[:4] == "--- ": break
432 if l[:4] == "--- ": break
405 text += l
433 text += l
406
434
407 # make sure text isn't empty
435 # make sure text isn't empty
408 if not text: text = "imported patch %s\n" % patch
436 if not text: text = "imported patch %s\n" % patch
409
437
410 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
438 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
411 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
439 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
412 f.close()
440 f.close()
413
441
414 if files:
442 if files:
415 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
443 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
416 raise "patch failed!"
444 raise "patch failed!"
417 repo.commit(files, text)
445 repo.commit(files, text)
418
446
419 def pull(ui, repo, source="default"):
447 def pull(ui, repo, source="default"):
420 """pull changes from the specified source"""
448 """pull changes from the specified source"""
421 paths = {}
449 paths = {}
422 for name, path in ui.configitems("paths"):
450 for name, path in ui.configitems("paths"):
423 paths[name] = path
451 paths[name] = path
424
452
425 if source in paths: source = paths[source]
453 if source in paths: source = paths[source]
426
454
427 other = hg.repository(ui, source)
455 other = hg.repository(ui, source)
428 cg = repo.getchangegroup(other)
456 cg = repo.getchangegroup(other)
429 repo.addchangegroup(cg)
457 repo.addchangegroup(cg)
430
458
431 def push(ui, repo, dest):
459 def push(ui, repo, dest):
432 """push changes to the specified destination"""
460 """push changes to the specified destination"""
433 paths = {}
461 paths = {}
434 for name, path in ui.configitems("paths"):
462 for name, path in ui.configitems("paths"):
435 paths[name] = path
463 paths[name] = path
436
464
437 if dest in paths: dest = paths[dest]
465 if dest in paths: dest = paths[dest]
438
466
439 if not dest.startswith("ssh://"):
467 if not dest.startswith("ssh://"):
440 ui.warn("abort: can only push to ssh:// destinations currently\n")
468 ui.warn("abort: can only push to ssh:// destinations currently\n")
441 return 1
469 return 1
442
470
443 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', dest)
471 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', dest)
444 if not m:
472 if not m:
445 ui.warn("abort: couldn't parse destination %s\n" % dest)
473 ui.warn("abort: couldn't parse destination %s\n" % dest)
446 return 1
474 return 1
447
475
448 user, host, port, path = map(m.group, (2, 3, 5, 7))
476 user, host, port, path = map(m.group, (2, 3, 5, 7))
449 host = user and ("%s@%s" % (user, host)) or host
477 host = user and ("%s@%s" % (user, host)) or host
450 port = port and (" -p %s") % port or ""
478 port = port and (" -p %s") % port or ""
451 path = path or ""
479 path = path or ""
452
480
453 sport = random.randrange(30000, 60000)
481 sport = random.randrange(30000, 60000)
454 cmd = "ssh %s%s -R %d:localhost:%d 'cd %s; hg pull http://localhost:%d/'"
482 cmd = "ssh %s%s -R %d:localhost:%d 'cd %s; hg pull http://localhost:%d/'"
455 cmd = cmd % (host, port, sport+1, sport, path, sport+1)
483 cmd = cmd % (host, port, sport+1, sport, path, sport+1)
456
484
457 child = os.fork()
485 child = os.fork()
458 if not child:
486 if not child:
459 sys.stdout = file("/dev/null", "w")
487 sys.stdout = file("/dev/null", "w")
460 sys.stderr = sys.stdout
488 sys.stderr = sys.stdout
461 hgweb.server(repo.root, "pull", "", "localhost", sport)
489 hgweb.server(repo.root, "pull", "", "localhost", sport)
462 else:
490 else:
463 r = os.system(cmd)
491 r = os.system(cmd)
464 os.kill(child, signal.SIGTERM)
492 os.kill(child, signal.SIGTERM)
465 return r
493 return r
466
494
467 def rawcommit(ui, repo, flist, **rc):
495 def rawcommit(ui, repo, flist, **rc):
468 "raw commit interface"
496 "raw commit interface"
469
497
470 text = rc['text']
498 text = rc['text']
471 if not text and rc['logfile']:
499 if not text and rc['logfile']:
472 try: text = open(rc['logfile']).read()
500 try: text = open(rc['logfile']).read()
473 except IOError: pass
501 except IOError: pass
474 if not text and not rc['logfile']:
502 if not text and not rc['logfile']:
475 print "missing commit text"
503 print "missing commit text"
476 return 1
504 return 1
477
505
478 files = relpath(repo, flist)
506 files = relpath(repo, flist)
479 if rc['files']:
507 if rc['files']:
480 files += open(rc['files']).read().splitlines()
508 files += open(rc['files']).read().splitlines()
481
509
482 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
510 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
483
511
484 def recover(ui, repo):
512 def recover(ui, repo):
485 """roll back an interrupted transaction"""
513 """roll back an interrupted transaction"""
486 repo.recover()
514 repo.recover()
487
515
488 def remove(ui, repo, file, *files):
516 def remove(ui, repo, file, *files):
489 """remove the specified files on the next commit"""
517 """remove the specified files on the next commit"""
490 repo.remove(relpath(repo, (file,) + files))
518 repo.remove(relpath(repo, (file,) + files))
491
519
492 def serve(ui, repo, **opts):
520 def serve(ui, repo, **opts):
493 """export the repository via HTTP"""
521 """export the repository via HTTP"""
494 hgweb.server(repo.root, opts["name"], opts["templates"],
522 hgweb.server(repo.root, opts["name"], opts["templates"],
495 opts["address"], opts["port"])
523 opts["address"], opts["port"])
496
524
497 def status(ui, repo):
525 def status(ui, repo):
498 '''show changed files in the working directory
526 '''show changed files in the working directory
499
527
500 C = changed
528 C = changed
501 A = added
529 A = added
502 R = removed
530 R = removed
503 ? = not tracked'''
531 ? = not tracked'''
504
532
505 (c, a, d, u) = repo.diffdir(os.getcwd())
533 (c, a, d, u) = repo.diffdir(os.getcwd())
506 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
534 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
507
535
508 for f in c: print "C", f
536 for f in c: print "C", f
509 for f in a: print "A", f
537 for f in a: print "A", f
510 for f in d: print "R", f
538 for f in d: print "R", f
511 for f in u: print "?", f
539 for f in u: print "?", f
512
540
513 def tags(ui, repo):
541 def tags(ui, repo):
514 """list repository tags"""
542 """list repository tags"""
515 repo.lookup(0) # prime the cache
543 n = tags_load(repo)
516 i = repo.tags.items()
517 n = []
518 for e in i:
519 try:
520 l = repo.changelog.rev(e[1])
521 except KeyError:
522 l = -2
523 n.append((l, e))
524
544
525 n.sort()
545 n.sort()
526 n.reverse()
546 n.reverse()
527 i = [ e[1] for e in n ]
547 i = [ e[1] for e in n ]
528 for k, n in i:
548 for k, n in i:
529 try:
549 try:
530 r = repo.changelog.rev(n)
550 r = repo.changelog.rev(n)
531 except KeyError:
551 except KeyError:
532 r = "?"
552 r = "?"
533 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
553 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
534
554
535 def tip(ui, repo):
555 def tip(ui, repo):
536 """show the tip revision"""
556 """show the tip revision"""
537 n = repo.changelog.tip()
557 n = repo.changelog.tip()
538 show_changeset(ui, repo, changenode=n)
558 show_changeset(ui, repo, changenode=n)
539
559
540 def undo(ui, repo):
560 def undo(ui, repo):
541 """undo the last transaction"""
561 """undo the last transaction"""
542 repo.undo()
562 repo.undo()
543
563
544 def update(ui, repo, node=None, merge=False, clean=False):
564 def update(ui, repo, node=None, merge=False, clean=False):
545 '''update or merge working directory
565 '''update or merge working directory
546
566
547 If there are no outstanding changes in the working directory and
567 If there are no outstanding changes in the working directory and
548 there is a linear relationship between the current version and the
568 there is a linear relationship between the current version and the
549 requested version, the result is the requested version.
569 requested version, the result is the requested version.
550
570
551 Otherwise the result is a merge between the contents of the
571 Otherwise the result is a merge between the contents of the
552 current working directory and the requested version. Files that
572 current working directory and the requested version. Files that
553 changed between either parent are marked as changed for the next
573 changed between either parent are marked as changed for the next
554 commit and a commit must be performed before any further updates
574 commit and a commit must be performed before any further updates
555 are allowed.
575 are allowed.
556 '''
576 '''
557 node = node and repo.lookup(node) or repo.changelog.tip()
577 node = node and repo.lookup(node) or repo.changelog.tip()
558 return repo.update(node, allow=merge, force=clean)
578 return repo.update(node, allow=merge, force=clean)
559
579
560 def verify(ui, repo):
580 def verify(ui, repo):
561 """verify the integrity of the repository"""
581 """verify the integrity of the repository"""
562 return repo.verify()
582 return repo.verify()
563
583
564 # Command options and aliases are listed here, alphabetically
584 # Command options and aliases are listed here, alphabetically
565
585
566 table = {
586 table = {
567 "add": (add, [], "hg add [files]"),
587 "add": (add, [], "hg add [files]"),
568 "addremove": (addremove, [], "hg addremove"),
588 "addremove": (addremove, [], "hg addremove"),
569 "ann|annotate": (annotate,
589 "ann|annotate": (annotate,
570 [('r', 'revision', '', 'revision'),
590 [('r', 'revision', '', 'revision'),
571 ('u', 'user', None, 'show user'),
591 ('u', 'user', None, 'show user'),
572 ('n', 'number', None, 'show revision number'),
592 ('n', 'number', None, 'show revision number'),
573 ('c', 'changeset', None, 'show changeset')],
593 ('c', 'changeset', None, 'show changeset')],
574 'hg annotate [-u] [-c] [-n] [-r id] [files]'),
594 'hg annotate [-u] [-c] [-n] [-r id] [files]'),
575 "cat|dump": (cat, [], 'hg cat <file> [rev]'),
595 "cat|dump": (cat, [], 'hg cat <file> [rev]'),
576 "commit|ci": (commit,
596 "commit|ci": (commit,
577 [('t', 'text', "", 'commit text'),
597 [('t', 'text', "", 'commit text'),
578 ('l', 'logfile', "", 'commit text file'),
598 ('l', 'logfile', "", 'commit text file'),
579 ('d', 'date', "", 'data'),
599 ('d', 'date', "", 'data'),
580 ('u', 'user', "", 'user')],
600 ('u', 'user', "", 'user')],
581 'hg commit [files]'),
601 'hg commit [files]'),
582 "debugaddchangegroup": (debugaddchangegroup, [], 'debugaddchangegroup'),
602 "debugaddchangegroup": (debugaddchangegroup, [], 'debugaddchangegroup'),
583 "debugchangegroup": (debugchangegroup, [], 'debugchangegroup [roots]'),
603 "debugchangegroup": (debugchangegroup, [], 'debugchangegroup [roots]'),
584 "debugindex": (debugindex, [], 'debugindex <file>'),
604 "debugindex": (debugindex, [], 'debugindex <file>'),
585 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'),
605 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'),
586 "diff": (diff, [('r', 'rev', [], 'revision')],
606 "diff": (diff, [('r', 'rev', [], 'revision')],
587 'hg diff [-r A] [-r B] [files]'),
607 'hg diff [-r A] [-r B] [files]'),
588 "export": (export, [], "hg export <changeset>"),
608 "export": (export, [], "hg export <changeset>"),
589 "forget": (forget, [], "hg forget [files]"),
609 "forget": (forget, [], "hg forget [files]"),
590 "heads": (heads, [], 'hg heads'),
610 "heads": (heads, [], 'hg heads'),
591 "history": (history, [], 'hg history'),
611 "history": (history, [], 'hg history'),
592 "help": (help, [], 'hg help [command]'),
612 "help": (help, [], 'hg help [command]'),
613 "identify|id": (identify, [], 'hg identify'),
593 "init": (init, [], 'hg init [url]'),
614 "init": (init, [], 'hg init [url]'),
594 "log": (log, [], 'hg log <file>'),
615 "log": (log, [], 'hg log <file>'),
595 "manifest|dumpmanifest": (manifest, [], 'hg manifest [rev]'),
616 "manifest|dumpmanifest": (manifest, [], 'hg manifest [rev]'),
596 "parents": (parents, [], 'hg parents [node]'),
617 "parents": (parents, [], 'hg parents [node]'),
597 "patch|import": (patch,
618 "patch|import": (patch,
598 [('p', 'strip', 1, 'path strip'),
619 [('p', 'strip', 1, 'path strip'),
599 ('b', 'base', "", 'base path'),
620 ('b', 'base', "", 'base path'),
600 ('q', 'quiet', "", 'silence diff')],
621 ('q', 'quiet', "", 'silence diff')],
601 "hg import [options] patches"),
622 "hg import [options] patches"),
602 "pull|merge": (pull, [], 'hg pull [source]'),
623 "pull|merge": (pull, [], 'hg pull [source]'),
603 "push": (push, [], 'hg push <destination>'),
624 "push": (push, [], 'hg push <destination>'),
604 "rawcommit": (rawcommit,
625 "rawcommit": (rawcommit,
605 [('p', 'parent', [], 'parent'),
626 [('p', 'parent', [], 'parent'),
606 ('d', 'date', "", 'data'),
627 ('d', 'date', "", 'data'),
607 ('u', 'user', "", 'user'),
628 ('u', 'user', "", 'user'),
608 ('F', 'files', "", 'file list'),
629 ('F', 'files', "", 'file list'),
609 ('t', 'text', "", 'commit text'),
630 ('t', 'text', "", 'commit text'),
610 ('l', 'logfile', "", 'commit text file')],
631 ('l', 'logfile', "", 'commit text file')],
611 'hg rawcommit [options] [files]'),
632 'hg rawcommit [options] [files]'),
612 "recover": (recover, [], "hg recover"),
633 "recover": (recover, [], "hg recover"),
613 "remove": (remove, [], "hg remove [files]"),
634 "remove": (remove, [], "hg remove [files]"),
614 "serve": (serve, [('p', 'port', 8000, 'listen port'),
635 "serve": (serve, [('p', 'port', 8000, 'listen port'),
615 ('a', 'address', '', 'interface address'),
636 ('a', 'address', '', 'interface address'),
616 ('n', 'name', os.getcwd(), 'repository name'),
637 ('n', 'name', os.getcwd(), 'repository name'),
617 ('t', 'templates', "", 'template map')],
638 ('t', 'templates', "", 'template map')],
618 "hg serve [options]"),
639 "hg serve [options]"),
619 "status": (status, [], 'hg status'),
640 "status": (status, [], 'hg status'),
620 "tags": (tags, [], 'hg tags'),
641 "tags": (tags, [], 'hg tags'),
621 "tip": (tip, [], 'hg tip'),
642 "tip": (tip, [], 'hg tip'),
622 "undo": (undo, [], 'hg undo'),
643 "undo": (undo, [], 'hg undo'),
623 "update|up|checkout|co|resolve": (update,
644 "update|up|checkout|co|resolve": (update,
624 [('m', 'merge', None,
645 [('m', 'merge', None,
625 'allow merging of conflicts'),
646 'allow merging of conflicts'),
626 ('C', 'clean', None,
647 ('C', 'clean', None,
627 'overwrite locally modified files')],
648 'overwrite locally modified files')],
628 'hg update [options] [node]'),
649 'hg update [options] [node]'),
629 "verify": (verify, [], 'hg verify'),
650 "verify": (verify, [], 'hg verify'),
630 }
651 }
631
652
632 norepo = "init branch help debugindex debugindexdot"
653 norepo = "init branch help debugindex debugindexdot"
633
654
634 def find(cmd):
655 def find(cmd):
635 i = None
656 i = None
636 for e in table.keys():
657 for e in table.keys():
637 if re.match("(%s)$" % e, cmd):
658 if re.match("(%s)$" % e, cmd):
638 return table[e]
659 return table[e]
639
660
640 raise UnknownCommand(cmd)
661 raise UnknownCommand(cmd)
641
662
642 class SignalInterrupt(Exception): pass
663 class SignalInterrupt(Exception): pass
643
664
644 def catchterm(*args):
665 def catchterm(*args):
645 raise SignalInterrupt
666 raise SignalInterrupt
646
667
647 def run():
668 def run():
648 sys.exit(dispatch(sys.argv[1:]))
669 sys.exit(dispatch(sys.argv[1:]))
649
670
650 def dispatch(args):
671 def dispatch(args):
651 options = {}
672 options = {}
652 opts = [('v', 'verbose', None, 'verbose'),
673 opts = [('v', 'verbose', None, 'verbose'),
653 ('d', 'debug', None, 'debug'),
674 ('d', 'debug', None, 'debug'),
654 ('q', 'quiet', None, 'quiet'),
675 ('q', 'quiet', None, 'quiet'),
655 ('p', 'profile', None, 'profile'),
676 ('p', 'profile', None, 'profile'),
656 ('y', 'noninteractive', None, 'run non-interactively'),
677 ('y', 'noninteractive', None, 'run non-interactively'),
657 ]
678 ]
658
679
659 args = fancyopts.fancyopts(args, opts, options,
680 args = fancyopts.fancyopts(args, opts, options,
660 'hg [options] <command> [options] [files]')
681 'hg [options] <command> [options] [files]')
661
682
662 if not args:
683 if not args:
663 cmd = "help"
684 cmd = "help"
664 else:
685 else:
665 cmd, args = args[0], args[1:]
686 cmd, args = args[0], args[1:]
666
687
667 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
688 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
668 not options["noninteractive"])
689 not options["noninteractive"])
669
690
670 try:
691 try:
671 i = find(cmd)
692 i = find(cmd)
672 except UnknownCommand:
693 except UnknownCommand:
673 u.warn("hg: unknown command '%s'\n" % cmd)
694 u.warn("hg: unknown command '%s'\n" % cmd)
674 help(u)
695 help(u)
675 sys.exit(1)
696 sys.exit(1)
676
697
677 signal.signal(signal.SIGTERM, catchterm)
698 signal.signal(signal.SIGTERM, catchterm)
678
699
679 cmdoptions = {}
700 cmdoptions = {}
680 try:
701 try:
681 args = fancyopts.fancyopts(args, i[1], cmdoptions, i[2])
702 args = fancyopts.fancyopts(args, i[1], cmdoptions, i[2])
682 except fancyopts.getopt.GetoptError, inst:
703 except fancyopts.getopt.GetoptError, inst:
683 u.warn("hg %s: %s\n" % (cmd, inst))
704 u.warn("hg %s: %s\n" % (cmd, inst))
684 help(u, cmd)
705 help(u, cmd)
685 sys.exit(-1)
706 sys.exit(-1)
686
707
687 if cmd not in norepo.split():
708 if cmd not in norepo.split():
688 repo = hg.repository(ui = u)
709 repo = hg.repository(ui = u)
689 d = lambda: i[0](u, repo, *args, **cmdoptions)
710 d = lambda: i[0](u, repo, *args, **cmdoptions)
690 else:
711 else:
691 d = lambda: i[0](u, *args, **cmdoptions)
712 d = lambda: i[0](u, *args, **cmdoptions)
692
713
693 try:
714 try:
694 if options['profile']:
715 if options['profile']:
695 import hotshot, hotshot.stats
716 import hotshot, hotshot.stats
696 prof = hotshot.Profile("hg.prof")
717 prof = hotshot.Profile("hg.prof")
697 r = prof.runcall(d)
718 r = prof.runcall(d)
698 prof.close()
719 prof.close()
699 stats = hotshot.stats.load("hg.prof")
720 stats = hotshot.stats.load("hg.prof")
700 stats.strip_dirs()
721 stats.strip_dirs()
701 stats.sort_stats('time', 'calls')
722 stats.sort_stats('time', 'calls')
702 stats.print_stats(40)
723 stats.print_stats(40)
703 return r
724 return r
704 else:
725 else:
705 return d()
726 return d()
706 except SignalInterrupt:
727 except SignalInterrupt:
707 u.warn("killed!\n")
728 u.warn("killed!\n")
708 except KeyboardInterrupt:
729 except KeyboardInterrupt:
709 u.warn("interrupted!\n")
730 u.warn("interrupted!\n")
710 except IOError, inst:
731 except IOError, inst:
711 if inst.errno == 32:
732 if inst.errno == 32:
712 u.warn("broken pipe\n")
733 u.warn("broken pipe\n")
713 else:
734 else:
714 raise
735 raise
715 except TypeError, inst:
736 except TypeError, inst:
716 # was this an argument error?
737 # was this an argument error?
717 tb = traceback.extract_tb(sys.exc_info()[2])
738 tb = traceback.extract_tb(sys.exc_info()[2])
718 if len(tb) > 2: # no
739 if len(tb) > 2: # no
719 raise
740 raise
720 u.debug(inst, "\n")
741 u.debug(inst, "\n")
721 u.warn("%s: invalid arguments\n" % i[0].__name__)
742 u.warn("%s: invalid arguments\n" % i[0].__name__)
722 help(u, cmd)
743 help(u, cmd)
723 sys.exit(-1)
744 sys.exit(-1)
724
745
General Comments 0
You need to be logged in to leave comments. Login now