##// END OF EJS Templates
Merge with stable
Henrik Stuart -
r9994:931d2c75 merge default
parent child Browse files
Show More
@@ -1,506 +1,511 b''
1 # dispatch.py - command dispatching for mercurial
1 # dispatch.py - command dispatching for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
7
7
8 from i18n import _
8 from i18n import _
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time
10 import util, commands, hg, fancyopts, extensions, hook, error
10 import util, commands, hg, fancyopts, extensions, hook, error
11 import cmdutil, encoding
11 import cmdutil, encoding
12 import ui as _ui
12 import ui as _ui
13
13
14 def run():
14 def run():
15 "run the command in sys.argv"
15 "run the command in sys.argv"
16 sys.exit(dispatch(sys.argv[1:]))
16 sys.exit(dispatch(sys.argv[1:]))
17
17
18 def dispatch(args):
18 def dispatch(args):
19 "run the command specified in args"
19 "run the command specified in args"
20 try:
20 try:
21 u = _ui.ui()
21 u = _ui.ui()
22 if '--traceback' in args:
22 if '--traceback' in args:
23 u.setconfig('ui', 'traceback', 'on')
23 u.setconfig('ui', 'traceback', 'on')
24 except util.Abort, inst:
24 except util.Abort, inst:
25 sys.stderr.write(_("abort: %s\n") % inst)
25 sys.stderr.write(_("abort: %s\n") % inst)
26 return -1
26 return -1
27 except error.ConfigError, inst:
27 except error.ConfigError, inst:
28 sys.stderr.write(_("hg: %s\n") % inst)
28 sys.stderr.write(_("hg: %s\n") % inst)
29 return -1
29 return -1
30 return _runcatch(u, args)
30 return _runcatch(u, args)
31
31
32 def _runcatch(ui, args):
32 def _runcatch(ui, args):
33 def catchterm(*args):
33 def catchterm(*args):
34 raise error.SignalInterrupt
34 raise error.SignalInterrupt
35
35
36 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
36 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
37 num = getattr(signal, name, None)
37 num = getattr(signal, name, None)
38 if num: signal.signal(num, catchterm)
38 if num: signal.signal(num, catchterm)
39
39
40 try:
40 try:
41 try:
41 try:
42 # enter the debugger before command execution
42 # enter the debugger before command execution
43 if '--debugger' in args:
43 if '--debugger' in args:
44 pdb.set_trace()
44 pdb.set_trace()
45 try:
45 try:
46 return _dispatch(ui, args)
46 return _dispatch(ui, args)
47 finally:
47 finally:
48 ui.flush()
48 ui.flush()
49 except:
49 except:
50 # enter the debugger when we hit an exception
50 # enter the debugger when we hit an exception
51 if '--debugger' in args:
51 if '--debugger' in args:
52 pdb.post_mortem(sys.exc_info()[2])
52 pdb.post_mortem(sys.exc_info()[2])
53 ui.traceback()
53 ui.traceback()
54 raise
54 raise
55
55
56 # Global exception handling, alphabetically
56 # Global exception handling, alphabetically
57 # Mercurial-specific first, followed by built-in and library exceptions
57 # Mercurial-specific first, followed by built-in and library exceptions
58 except error.AmbiguousCommand, inst:
58 except error.AmbiguousCommand, inst:
59 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
59 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
60 (inst.args[0], " ".join(inst.args[1])))
60 (inst.args[0], " ".join(inst.args[1])))
61 except error.ConfigError, inst:
61 except error.ConfigError, inst:
62 ui.warn(_("hg: %s\n") % inst.args[0])
62 ui.warn(_("hg: %s\n") % inst.args[0])
63 except error.LockHeld, inst:
63 except error.LockHeld, inst:
64 if inst.errno == errno.ETIMEDOUT:
64 if inst.errno == errno.ETIMEDOUT:
65 reason = _('timed out waiting for lock held by %s') % inst.locker
65 reason = _('timed out waiting for lock held by %s') % inst.locker
66 else:
66 else:
67 reason = _('lock held by %s') % inst.locker
67 reason = _('lock held by %s') % inst.locker
68 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
68 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
69 except error.LockUnavailable, inst:
69 except error.LockUnavailable, inst:
70 ui.warn(_("abort: could not lock %s: %s\n") %
70 ui.warn(_("abort: could not lock %s: %s\n") %
71 (inst.desc or inst.filename, inst.strerror))
71 (inst.desc or inst.filename, inst.strerror))
72 except error.ParseError, inst:
72 except error.ParseError, inst:
73 if inst.args[0]:
73 if inst.args[0]:
74 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
74 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
75 commands.help_(ui, inst.args[0])
75 commands.help_(ui, inst.args[0])
76 else:
76 else:
77 ui.warn(_("hg: %s\n") % inst.args[1])
77 ui.warn(_("hg: %s\n") % inst.args[1])
78 commands.help_(ui, 'shortlist')
78 commands.help_(ui, 'shortlist')
79 except error.RepoError, inst:
79 except error.RepoError, inst:
80 ui.warn(_("abort: %s!\n") % inst)
80 ui.warn(_("abort: %s!\n") % inst)
81 except error.ResponseError, inst:
81 except error.ResponseError, inst:
82 ui.warn(_("abort: %s") % inst.args[0])
82 ui.warn(_("abort: %s") % inst.args[0])
83 if not isinstance(inst.args[1], basestring):
83 if not isinstance(inst.args[1], basestring):
84 ui.warn(" %r\n" % (inst.args[1],))
84 ui.warn(" %r\n" % (inst.args[1],))
85 elif not inst.args[1]:
85 elif not inst.args[1]:
86 ui.warn(_(" empty string\n"))
86 ui.warn(_(" empty string\n"))
87 else:
87 else:
88 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
88 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
89 except error.RevlogError, inst:
89 except error.RevlogError, inst:
90 ui.warn(_("abort: %s!\n") % inst)
90 ui.warn(_("abort: %s!\n") % inst)
91 except error.SignalInterrupt:
91 except error.SignalInterrupt:
92 ui.warn(_("killed!\n"))
92 ui.warn(_("killed!\n"))
93 except error.UnknownCommand, inst:
93 except error.UnknownCommand, inst:
94 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
94 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
95 commands.help_(ui, 'shortlist')
95 commands.help_(ui, 'shortlist')
96 except util.Abort, inst:
96 except util.Abort, inst:
97 ui.warn(_("abort: %s\n") % inst)
97 ui.warn(_("abort: %s\n") % inst)
98 except ImportError, inst:
98 except ImportError, inst:
99 m = str(inst).split()[-1]
99 m = str(inst).split()[-1]
100 ui.warn(_("abort: could not import module %s!\n") % m)
100 ui.warn(_("abort: could not import module %s!\n") % m)
101 if m in "mpatch bdiff".split():
101 if m in "mpatch bdiff".split():
102 ui.warn(_("(did you forget to compile extensions?)\n"))
102 ui.warn(_("(did you forget to compile extensions?)\n"))
103 elif m in "zlib".split():
103 elif m in "zlib".split():
104 ui.warn(_("(is your Python install correct?)\n"))
104 ui.warn(_("(is your Python install correct?)\n"))
105 except IOError, inst:
105 except IOError, inst:
106 if hasattr(inst, "code"):
106 if hasattr(inst, "code"):
107 ui.warn(_("abort: %s\n") % inst)
107 ui.warn(_("abort: %s\n") % inst)
108 elif hasattr(inst, "reason"):
108 elif hasattr(inst, "reason"):
109 try: # usually it is in the form (errno, strerror)
109 try: # usually it is in the form (errno, strerror)
110 reason = inst.reason.args[1]
110 reason = inst.reason.args[1]
111 except: # it might be anything, for example a string
111 except: # it might be anything, for example a string
112 reason = inst.reason
112 reason = inst.reason
113 ui.warn(_("abort: error: %s\n") % reason)
113 ui.warn(_("abort: error: %s\n") % reason)
114 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
114 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
115 if ui.debugflag:
115 if ui.debugflag:
116 ui.warn(_("broken pipe\n"))
116 ui.warn(_("broken pipe\n"))
117 elif getattr(inst, "strerror", None):
117 elif getattr(inst, "strerror", None):
118 if getattr(inst, "filename", None):
118 if getattr(inst, "filename", None):
119 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
119 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
120 else:
120 else:
121 ui.warn(_("abort: %s\n") % inst.strerror)
121 ui.warn(_("abort: %s\n") % inst.strerror)
122 else:
122 else:
123 raise
123 raise
124 except OSError, inst:
124 except OSError, inst:
125 if getattr(inst, "filename", None):
125 if getattr(inst, "filename", None):
126 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
126 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
127 else:
127 else:
128 ui.warn(_("abort: %s\n") % inst.strerror)
128 ui.warn(_("abort: %s\n") % inst.strerror)
129 except KeyboardInterrupt:
129 except KeyboardInterrupt:
130 try:
130 try:
131 ui.warn(_("interrupted!\n"))
131 ui.warn(_("interrupted!\n"))
132 except IOError, inst:
132 except IOError, inst:
133 if inst.errno == errno.EPIPE:
133 if inst.errno == errno.EPIPE:
134 if ui.debugflag:
134 if ui.debugflag:
135 ui.warn(_("\nbroken pipe\n"))
135 ui.warn(_("\nbroken pipe\n"))
136 else:
136 else:
137 raise
137 raise
138 except MemoryError:
138 except MemoryError:
139 ui.warn(_("abort: out of memory\n"))
139 ui.warn(_("abort: out of memory\n"))
140 except SystemExit, inst:
140 except SystemExit, inst:
141 # Commands shouldn't sys.exit directly, but give a return code.
141 # Commands shouldn't sys.exit directly, but give a return code.
142 # Just in case catch this and and pass exit code to caller.
142 # Just in case catch this and and pass exit code to caller.
143 return inst.code
143 return inst.code
144 except socket.error, inst:
144 except socket.error, inst:
145 ui.warn(_("abort: %s\n") % inst.args[-1])
145 ui.warn(_("abort: %s\n") % inst.args[-1])
146 except:
146 except:
147 ui.warn(_("** unknown exception encountered, details follow\n"))
147 ui.warn(_("** unknown exception encountered, details follow\n"))
148 ui.warn(_("** report bug details to "
148 ui.warn(_("** report bug details to "
149 "http://mercurial.selenic.com/bts/\n"))
149 "http://mercurial.selenic.com/bts/\n"))
150 ui.warn(_("** or mercurial@selenic.com\n"))
150 ui.warn(_("** or mercurial@selenic.com\n"))
151 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
151 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
152 % util.version())
152 % util.version())
153 ui.warn(_("** Extensions loaded: %s\n")
153 ui.warn(_("** Extensions loaded: %s\n")
154 % ", ".join([x[0] for x in extensions.extensions()]))
154 % ", ".join([x[0] for x in extensions.extensions()]))
155 raise
155 raise
156
156
157 return -1
157 return -1
158
158
159 def _findrepo(p):
159 def _findrepo(p):
160 while not os.path.isdir(os.path.join(p, ".hg")):
160 while not os.path.isdir(os.path.join(p, ".hg")):
161 oldp, p = p, os.path.dirname(p)
161 oldp, p = p, os.path.dirname(p)
162 if p == oldp:
162 if p == oldp:
163 return None
163 return None
164
164
165 return p
165 return p
166
166
167 def aliasargs(fn):
167 def aliasargs(fn):
168 if hasattr(fn, 'args'):
168 if hasattr(fn, 'args'):
169 return fn.args
169 return fn.args
170 return []
170 return []
171
171
172 class cmdalias(object):
172 class cmdalias(object):
173 def __init__(self, name, definition, cmdtable):
173 def __init__(self, name, definition, cmdtable):
174 self.name = name
174 self.name = name
175 self.definition = definition
175 self.definition = definition
176 self.args = []
176 self.args = []
177 self.opts = []
177 self.opts = []
178 self.help = ''
178 self.help = ''
179 self.norepo = True
179 self.norepo = True
180
180
181 try:
181 try:
182 cmdutil.findcmd(self.name, cmdtable, True)
182 cmdutil.findcmd(self.name, cmdtable, True)
183 self.shadows = True
183 self.shadows = True
184 except error.UnknownCommand:
184 except error.UnknownCommand:
185 self.shadows = False
185 self.shadows = False
186
186
187 if not self.definition:
187 if not self.definition:
188 def fn(ui, *args):
188 def fn(ui, *args):
189 ui.warn(_("no definition for alias '%s'\n") % self.name)
189 ui.warn(_("no definition for alias '%s'\n") % self.name)
190 return 1
190 return 1
191 self.fn = fn
191 self.fn = fn
192
192
193 return
193 return
194
194
195 args = shlex.split(self.definition)
195 args = shlex.split(self.definition)
196 cmd = args.pop(0)
196 cmd = args.pop(0)
197
197
198 try:
198 try:
199 self.fn, self.opts, self.help = cmdutil.findcmd(cmd, cmdtable, False)[1]
199 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
200 if len(tableentry) > 2:
201 self.fn, self.opts, self.help = tableentry
202 else:
203 self.fn, self.opts = tableentry
204
200 self.args = aliasargs(self.fn) + args
205 self.args = aliasargs(self.fn) + args
201 if cmd not in commands.norepo.split(' '):
206 if cmd not in commands.norepo.split(' '):
202 self.norepo = False
207 self.norepo = False
203 if self.help.startswith("hg " + cmd):
208 if self.help.startswith("hg " + cmd):
204 # drop prefix in old-style help lines so hg shows the alias
209 # drop prefix in old-style help lines so hg shows the alias
205 self.help = self.help[4 + len(cmd):]
210 self.help = self.help[4 + len(cmd):]
206 self.__doc__ = _("alias for: hg %s\n\n%s") \
211 self.__doc__ = _("alias for: hg %s\n\n%s") \
207 % (definition, self.fn.__doc__)
212 % (definition, self.fn.__doc__)
208
213
209 except error.UnknownCommand:
214 except error.UnknownCommand:
210 def fn(ui, *args):
215 def fn(ui, *args):
211 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
216 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
212 % (self.name, cmd))
217 % (self.name, cmd))
213 return 1
218 return 1
214 self.fn = fn
219 self.fn = fn
215 except error.AmbiguousCommand:
220 except error.AmbiguousCommand:
216 def fn(ui, *args):
221 def fn(ui, *args):
217 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
222 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
218 % (self.name, cmd))
223 % (self.name, cmd))
219 return 1
224 return 1
220 self.fn = fn
225 self.fn = fn
221
226
222 def __call__(self, ui, *args, **opts):
227 def __call__(self, ui, *args, **opts):
223 if self.shadows:
228 if self.shadows:
224 ui.debug("alias '%s' shadows command\n" % self.name)
229 ui.debug("alias '%s' shadows command\n" % self.name)
225
230
226 return self.fn(ui, *args, **opts)
231 return self.fn(ui, *args, **opts)
227
232
228 def addaliases(ui, cmdtable):
233 def addaliases(ui, cmdtable):
229 # aliases are processed after extensions have been loaded, so they
234 # aliases are processed after extensions have been loaded, so they
230 # may use extension commands. Aliases can also use other alias definitions,
235 # may use extension commands. Aliases can also use other alias definitions,
231 # but only if they have been defined prior to the current definition.
236 # but only if they have been defined prior to the current definition.
232 for alias, definition in ui.configitems('alias'):
237 for alias, definition in ui.configitems('alias'):
233 aliasdef = cmdalias(alias, definition, cmdtable)
238 aliasdef = cmdalias(alias, definition, cmdtable)
234 cmdtable[alias] = (aliasdef, aliasdef.opts, aliasdef.help)
239 cmdtable[alias] = (aliasdef, aliasdef.opts, aliasdef.help)
235 if aliasdef.norepo:
240 if aliasdef.norepo:
236 commands.norepo += ' %s' % alias
241 commands.norepo += ' %s' % alias
237
242
238 def _parse(ui, args):
243 def _parse(ui, args):
239 options = {}
244 options = {}
240 cmdoptions = {}
245 cmdoptions = {}
241
246
242 try:
247 try:
243 args = fancyopts.fancyopts(args, commands.globalopts, options)
248 args = fancyopts.fancyopts(args, commands.globalopts, options)
244 except fancyopts.getopt.GetoptError, inst:
249 except fancyopts.getopt.GetoptError, inst:
245 raise error.ParseError(None, inst)
250 raise error.ParseError(None, inst)
246
251
247 if args:
252 if args:
248 cmd, args = args[0], args[1:]
253 cmd, args = args[0], args[1:]
249 aliases, entry = cmdutil.findcmd(cmd, commands.table,
254 aliases, entry = cmdutil.findcmd(cmd, commands.table,
250 ui.config("ui", "strict"))
255 ui.config("ui", "strict"))
251 cmd = aliases[0]
256 cmd = aliases[0]
252 args = aliasargs(entry[0]) + args
257 args = aliasargs(entry[0]) + args
253 defaults = ui.config("defaults", cmd)
258 defaults = ui.config("defaults", cmd)
254 if defaults:
259 if defaults:
255 args = map(util.expandpath, shlex.split(defaults)) + args
260 args = map(util.expandpath, shlex.split(defaults)) + args
256 c = list(entry[1])
261 c = list(entry[1])
257 else:
262 else:
258 cmd = None
263 cmd = None
259 c = []
264 c = []
260
265
261 # combine global options into local
266 # combine global options into local
262 for o in commands.globalopts:
267 for o in commands.globalopts:
263 c.append((o[0], o[1], options[o[1]], o[3]))
268 c.append((o[0], o[1], options[o[1]], o[3]))
264
269
265 try:
270 try:
266 args = fancyopts.fancyopts(args, c, cmdoptions, True)
271 args = fancyopts.fancyopts(args, c, cmdoptions, True)
267 except fancyopts.getopt.GetoptError, inst:
272 except fancyopts.getopt.GetoptError, inst:
268 raise error.ParseError(cmd, inst)
273 raise error.ParseError(cmd, inst)
269
274
270 # separate global options back out
275 # separate global options back out
271 for o in commands.globalopts:
276 for o in commands.globalopts:
272 n = o[1]
277 n = o[1]
273 options[n] = cmdoptions[n]
278 options[n] = cmdoptions[n]
274 del cmdoptions[n]
279 del cmdoptions[n]
275
280
276 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
281 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
277
282
278 def _parseconfig(ui, config):
283 def _parseconfig(ui, config):
279 """parse the --config options from the command line"""
284 """parse the --config options from the command line"""
280 for cfg in config:
285 for cfg in config:
281 try:
286 try:
282 name, value = cfg.split('=', 1)
287 name, value = cfg.split('=', 1)
283 section, name = name.split('.', 1)
288 section, name = name.split('.', 1)
284 if not section or not name:
289 if not section or not name:
285 raise IndexError
290 raise IndexError
286 ui.setconfig(section, name, value)
291 ui.setconfig(section, name, value)
287 except (IndexError, ValueError):
292 except (IndexError, ValueError):
288 raise util.Abort(_('malformed --config option: %r '
293 raise util.Abort(_('malformed --config option: %r '
289 '(use --config section.name=value)') % cfg)
294 '(use --config section.name=value)') % cfg)
290
295
291 def _earlygetopt(aliases, args):
296 def _earlygetopt(aliases, args):
292 """Return list of values for an option (or aliases).
297 """Return list of values for an option (or aliases).
293
298
294 The values are listed in the order they appear in args.
299 The values are listed in the order they appear in args.
295 The options and values are removed from args.
300 The options and values are removed from args.
296 """
301 """
297 try:
302 try:
298 argcount = args.index("--")
303 argcount = args.index("--")
299 except ValueError:
304 except ValueError:
300 argcount = len(args)
305 argcount = len(args)
301 shortopts = [opt for opt in aliases if len(opt) == 2]
306 shortopts = [opt for opt in aliases if len(opt) == 2]
302 values = []
307 values = []
303 pos = 0
308 pos = 0
304 while pos < argcount:
309 while pos < argcount:
305 if args[pos] in aliases:
310 if args[pos] in aliases:
306 if pos + 1 >= argcount:
311 if pos + 1 >= argcount:
307 # ignore and let getopt report an error if there is no value
312 # ignore and let getopt report an error if there is no value
308 break
313 break
309 del args[pos]
314 del args[pos]
310 values.append(args.pop(pos))
315 values.append(args.pop(pos))
311 argcount -= 2
316 argcount -= 2
312 elif args[pos][:2] in shortopts:
317 elif args[pos][:2] in shortopts:
313 # short option can have no following space, e.g. hg log -Rfoo
318 # short option can have no following space, e.g. hg log -Rfoo
314 values.append(args.pop(pos)[2:])
319 values.append(args.pop(pos)[2:])
315 argcount -= 1
320 argcount -= 1
316 else:
321 else:
317 pos += 1
322 pos += 1
318 return values
323 return values
319
324
320 def runcommand(lui, repo, cmd, fullargs, ui, options, d):
325 def runcommand(lui, repo, cmd, fullargs, ui, options, d):
321 # run pre-hook, and abort if it fails
326 # run pre-hook, and abort if it fails
322 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
327 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
323 if ret:
328 if ret:
324 return ret
329 return ret
325 ret = _runcommand(ui, options, cmd, d)
330 ret = _runcommand(ui, options, cmd, d)
326 # run post-hook, passing command result
331 # run post-hook, passing command result
327 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
332 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
328 result = ret)
333 result = ret)
329 return ret
334 return ret
330
335
331 _loaded = set()
336 _loaded = set()
332 def _dispatch(ui, args):
337 def _dispatch(ui, args):
333 # read --config before doing anything else
338 # read --config before doing anything else
334 # (e.g. to change trust settings for reading .hg/hgrc)
339 # (e.g. to change trust settings for reading .hg/hgrc)
335 _parseconfig(ui, _earlygetopt(['--config'], args))
340 _parseconfig(ui, _earlygetopt(['--config'], args))
336
341
337 # check for cwd
342 # check for cwd
338 cwd = _earlygetopt(['--cwd'], args)
343 cwd = _earlygetopt(['--cwd'], args)
339 if cwd:
344 if cwd:
340 os.chdir(cwd[-1])
345 os.chdir(cwd[-1])
341
346
342 # read the local repository .hgrc into a local ui object
347 # read the local repository .hgrc into a local ui object
343 path = _findrepo(os.getcwd()) or ""
348 path = _findrepo(os.getcwd()) or ""
344 if not path:
349 if not path:
345 lui = ui
350 lui = ui
346 else:
351 else:
347 try:
352 try:
348 lui = ui.copy()
353 lui = ui.copy()
349 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
354 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
350 except IOError:
355 except IOError:
351 pass
356 pass
352
357
353 # now we can expand paths, even ones in .hg/hgrc
358 # now we can expand paths, even ones in .hg/hgrc
354 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
359 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
355 if rpath:
360 if rpath:
356 path = lui.expandpath(rpath[-1])
361 path = lui.expandpath(rpath[-1])
357 lui = ui.copy()
362 lui = ui.copy()
358 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
363 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
359
364
360 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
365 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
361 # reposetup. Programs like TortoiseHg will call _dispatch several
366 # reposetup. Programs like TortoiseHg will call _dispatch several
362 # times so we keep track of configured extensions in _loaded.
367 # times so we keep track of configured extensions in _loaded.
363 extensions.loadall(lui)
368 extensions.loadall(lui)
364 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
369 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
365
370
366 # (uisetup and extsetup are handled in extensions.loadall)
371 # (uisetup and extsetup are handled in extensions.loadall)
367
372
368 for name, module in exts:
373 for name, module in exts:
369 cmdtable = getattr(module, 'cmdtable', {})
374 cmdtable = getattr(module, 'cmdtable', {})
370 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
375 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
371 if overrides:
376 if overrides:
372 ui.warn(_("extension '%s' overrides commands: %s\n")
377 ui.warn(_("extension '%s' overrides commands: %s\n")
373 % (name, " ".join(overrides)))
378 % (name, " ".join(overrides)))
374 commands.table.update(cmdtable)
379 commands.table.update(cmdtable)
375 _loaded.add(name)
380 _loaded.add(name)
376
381
377 # (reposetup is handled in hg.repository)
382 # (reposetup is handled in hg.repository)
378
383
379 addaliases(lui, commands.table)
384 addaliases(lui, commands.table)
380
385
381 # check for fallback encoding
386 # check for fallback encoding
382 fallback = lui.config('ui', 'fallbackencoding')
387 fallback = lui.config('ui', 'fallbackencoding')
383 if fallback:
388 if fallback:
384 encoding.fallbackencoding = fallback
389 encoding.fallbackencoding = fallback
385
390
386 fullargs = args
391 fullargs = args
387 cmd, func, args, options, cmdoptions = _parse(lui, args)
392 cmd, func, args, options, cmdoptions = _parse(lui, args)
388
393
389 if options["config"]:
394 if options["config"]:
390 raise util.Abort(_("Option --config may not be abbreviated!"))
395 raise util.Abort(_("Option --config may not be abbreviated!"))
391 if options["cwd"]:
396 if options["cwd"]:
392 raise util.Abort(_("Option --cwd may not be abbreviated!"))
397 raise util.Abort(_("Option --cwd may not be abbreviated!"))
393 if options["repository"]:
398 if options["repository"]:
394 raise util.Abort(_(
399 raise util.Abort(_(
395 "Option -R has to be separated from other options (e.g. not -qR) "
400 "Option -R has to be separated from other options (e.g. not -qR) "
396 "and --repository may only be abbreviated as --repo!"))
401 "and --repository may only be abbreviated as --repo!"))
397
402
398 if options["encoding"]:
403 if options["encoding"]:
399 encoding.encoding = options["encoding"]
404 encoding.encoding = options["encoding"]
400 if options["encodingmode"]:
405 if options["encodingmode"]:
401 encoding.encodingmode = options["encodingmode"]
406 encoding.encodingmode = options["encodingmode"]
402 if options["time"]:
407 if options["time"]:
403 def get_times():
408 def get_times():
404 t = os.times()
409 t = os.times()
405 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
410 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
406 t = (t[0], t[1], t[2], t[3], time.clock())
411 t = (t[0], t[1], t[2], t[3], time.clock())
407 return t
412 return t
408 s = get_times()
413 s = get_times()
409 def print_time():
414 def print_time():
410 t = get_times()
415 t = get_times()
411 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
416 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
412 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
417 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
413 atexit.register(print_time)
418 atexit.register(print_time)
414
419
415 if options['verbose'] or options['debug'] or options['quiet']:
420 if options['verbose'] or options['debug'] or options['quiet']:
416 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
421 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
417 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
422 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
418 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
423 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
419 if options['traceback']:
424 if options['traceback']:
420 ui.setconfig('ui', 'traceback', 'on')
425 ui.setconfig('ui', 'traceback', 'on')
421 if options['noninteractive']:
426 if options['noninteractive']:
422 ui.setconfig('ui', 'interactive', 'off')
427 ui.setconfig('ui', 'interactive', 'off')
423
428
424 if options['help']:
429 if options['help']:
425 return commands.help_(ui, cmd, options['version'])
430 return commands.help_(ui, cmd, options['version'])
426 elif options['version']:
431 elif options['version']:
427 return commands.version_(ui)
432 return commands.version_(ui)
428 elif not cmd:
433 elif not cmd:
429 return commands.help_(ui, 'shortlist')
434 return commands.help_(ui, 'shortlist')
430
435
431 repo = None
436 repo = None
432 if cmd not in commands.norepo.split():
437 if cmd not in commands.norepo.split():
433 try:
438 try:
434 repo = hg.repository(ui, path=path)
439 repo = hg.repository(ui, path=path)
435 ui = repo.ui
440 ui = repo.ui
436 if not repo.local():
441 if not repo.local():
437 raise util.Abort(_("repository '%s' is not local") % path)
442 raise util.Abort(_("repository '%s' is not local") % path)
438 ui.setconfig("bundle", "mainreporoot", repo.root)
443 ui.setconfig("bundle", "mainreporoot", repo.root)
439 except error.RepoError:
444 except error.RepoError:
440 if cmd not in commands.optionalrepo.split():
445 if cmd not in commands.optionalrepo.split():
441 if args and not path: # try to infer -R from command args
446 if args and not path: # try to infer -R from command args
442 repos = map(_findrepo, args)
447 repos = map(_findrepo, args)
443 guess = repos[0]
448 guess = repos[0]
444 if guess and repos.count(guess) == len(repos):
449 if guess and repos.count(guess) == len(repos):
445 return _dispatch(ui, ['--repository', guess] + fullargs)
450 return _dispatch(ui, ['--repository', guess] + fullargs)
446 if not path:
451 if not path:
447 raise error.RepoError(_("There is no Mercurial repository"
452 raise error.RepoError(_("There is no Mercurial repository"
448 " here (.hg not found)"))
453 " here (.hg not found)"))
449 raise
454 raise
450 args.insert(0, repo)
455 args.insert(0, repo)
451 elif rpath:
456 elif rpath:
452 ui.warn("warning: --repository ignored\n")
457 ui.warn("warning: --repository ignored\n")
453
458
454 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
459 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
455 return runcommand(lui, repo, cmd, fullargs, ui, options, d)
460 return runcommand(lui, repo, cmd, fullargs, ui, options, d)
456
461
457 def _runcommand(ui, options, cmd, cmdfunc):
462 def _runcommand(ui, options, cmd, cmdfunc):
458 def checkargs():
463 def checkargs():
459 try:
464 try:
460 return cmdfunc()
465 return cmdfunc()
461 except error.SignatureError:
466 except error.SignatureError:
462 raise error.ParseError(cmd, _("invalid arguments"))
467 raise error.ParseError(cmd, _("invalid arguments"))
463
468
464 if options['profile']:
469 if options['profile']:
465 format = ui.config('profiling', 'format', default='text')
470 format = ui.config('profiling', 'format', default='text')
466
471
467 if not format in ['text', 'kcachegrind']:
472 if not format in ['text', 'kcachegrind']:
468 ui.warn(_("unrecognized profiling format '%s'"
473 ui.warn(_("unrecognized profiling format '%s'"
469 " - Ignored\n") % format)
474 " - Ignored\n") % format)
470 format = 'text'
475 format = 'text'
471
476
472 output = ui.config('profiling', 'output')
477 output = ui.config('profiling', 'output')
473
478
474 if output:
479 if output:
475 path = ui.expandpath(output)
480 path = ui.expandpath(output)
476 ostream = open(path, 'wb')
481 ostream = open(path, 'wb')
477 else:
482 else:
478 ostream = sys.stderr
483 ostream = sys.stderr
479
484
480 try:
485 try:
481 from mercurial import lsprof
486 from mercurial import lsprof
482 except ImportError:
487 except ImportError:
483 raise util.Abort(_(
488 raise util.Abort(_(
484 'lsprof not available - install from '
489 'lsprof not available - install from '
485 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
490 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
486 p = lsprof.Profiler()
491 p = lsprof.Profiler()
487 p.enable(subcalls=True)
492 p.enable(subcalls=True)
488 try:
493 try:
489 return checkargs()
494 return checkargs()
490 finally:
495 finally:
491 p.disable()
496 p.disable()
492
497
493 if format == 'kcachegrind':
498 if format == 'kcachegrind':
494 import lsprofcalltree
499 import lsprofcalltree
495 calltree = lsprofcalltree.KCacheGrind(p)
500 calltree = lsprofcalltree.KCacheGrind(p)
496 calltree.output(ostream)
501 calltree.output(ostream)
497 else:
502 else:
498 # format == 'text'
503 # format == 'text'
499 stats = lsprof.Stats(p.getstats())
504 stats = lsprof.Stats(p.getstats())
500 stats.sort()
505 stats.sort()
501 stats.pprint(top=10, file=ostream, climit=5)
506 stats.pprint(top=10, file=ostream, climit=5)
502
507
503 if output:
508 if output:
504 ostream.close()
509 ostream.close()
505 else:
510 else:
506 return checkargs()
511 return checkargs()
@@ -1,52 +1,57 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 cat >> $HGRCPATH <<EOF
3 cat >> $HGRCPATH <<EOF
4 [alias]
4 [alias]
5 myinit = init
5 myinit = init
6 cleanstatus = status -c
6 cleanstatus = status -c
7 unknown = bargle
7 unknown = bargle
8 ambiguous = s
8 ambiguous = s
9 recursive = recursive
9 recursive = recursive
10 nodefinition =
10 nodefinition =
11 mylog = log
11 mylog = log
12 lognull = log -r null
12 lognull = log -r null
13 shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
13 shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
14 dln = lognull --debug
14 dln = lognull --debug
15 nousage = rollback
15
16
16 [defaults]
17 [defaults]
17 mylog = -q
18 mylog = -q
18 lognull = -q
19 lognull = -q
19 log = -v
20 log = -v
20 EOF
21 EOF
21
22
22 echo '% basic'
23 echo '% basic'
23 hg myinit alias
24 hg myinit alias
24
25
25 echo '% unknown'
26 echo '% unknown'
26 hg unknown
27 hg unknown
27
28
28 echo '% ambiguous'
29 echo '% ambiguous'
29 hg ambiguous
30 hg ambiguous
30
31
31 echo '% recursive'
32 echo '% recursive'
32 hg recursive
33 hg recursive
33
34
34 echo '% no definition'
35 echo '% no definition'
35 hg nodef
36 hg nodef
36
37
37 cd alias
38 cd alias
39
40 echo '% no usage'
41 hg nousage
42
38 echo foo > foo
43 echo foo > foo
39 hg ci -Amfoo
44 hg ci -Amfoo
40
45
41 echo '% with opts'
46 echo '% with opts'
42 hg cleanst
47 hg cleanst
43
48
44 echo '% with opts and whitespace'
49 echo '% with opts and whitespace'
45 hg shortlog
50 hg shortlog
46
51
47 echo '% interaction with defaults'
52 echo '% interaction with defaults'
48 hg mylog
53 hg mylog
49 hg lognull
54 hg lognull
50
55
51 echo '% properly recursive'
56 echo '% properly recursive'
52 hg dln
57 hg dln
@@ -1,26 +1,28 b''
1 % basic
1 % basic
2 % unknown
2 % unknown
3 alias 'unknown' resolves to unknown command 'bargle'
3 alias 'unknown' resolves to unknown command 'bargle'
4 % ambiguous
4 % ambiguous
5 alias 'ambiguous' resolves to ambiguous command 's'
5 alias 'ambiguous' resolves to ambiguous command 's'
6 % recursive
6 % recursive
7 alias 'recursive' resolves to unknown command 'recursive'
7 alias 'recursive' resolves to unknown command 'recursive'
8 % no definition
8 % no definition
9 no definition for alias 'nodefinition'
9 no definition for alias 'nodefinition'
10 % no usage
11 no rollback information available
10 adding foo
12 adding foo
11 % with opts
13 % with opts
12 C foo
14 C foo
13 % with opts and whitespace
15 % with opts and whitespace
14 0 e63c23eaa88a | 1970-01-01 00:00 +0000
16 0 e63c23eaa88a | 1970-01-01 00:00 +0000
15 % interaction with defaults
17 % interaction with defaults
16 0:e63c23eaa88a
18 0:e63c23eaa88a
17 -1:000000000000
19 -1:000000000000
18 % properly recursive
20 % properly recursive
19 changeset: -1:0000000000000000000000000000000000000000
21 changeset: -1:0000000000000000000000000000000000000000
20 parent: -1:0000000000000000000000000000000000000000
22 parent: -1:0000000000000000000000000000000000000000
21 parent: -1:0000000000000000000000000000000000000000
23 parent: -1:0000000000000000000000000000000000000000
22 manifest: -1:0000000000000000000000000000000000000000
24 manifest: -1:0000000000000000000000000000000000000000
23 user:
25 user:
24 date: Thu Jan 01 00:00:00 1970 +0000
26 date: Thu Jan 01 00:00:00 1970 +0000
25 extra: branch=default
27 extra: branch=default
26
28
General Comments 0
You need to be logged in to leave comments. Login now