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