##// END OF EJS Templates
alias: inherit command optionalrepo flag (issue3298)...
Patrick Mezard -
r16609:d36a384b stable
parent child Browse files
Show More
@@ -1,776 +1,786
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 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time, traceback, re
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 uimod
12 import ui as uimod
13
13
14 class request(object):
14 class request(object):
15 def __init__(self, args, ui=None, repo=None, fin=None, fout=None, ferr=None):
15 def __init__(self, args, ui=None, repo=None, fin=None, fout=None, ferr=None):
16 self.args = args
16 self.args = args
17 self.ui = ui
17 self.ui = ui
18 self.repo = repo
18 self.repo = repo
19
19
20 # input/output/error streams
20 # input/output/error streams
21 self.fin = fin
21 self.fin = fin
22 self.fout = fout
22 self.fout = fout
23 self.ferr = ferr
23 self.ferr = ferr
24
24
25 def run():
25 def run():
26 "run the command in sys.argv"
26 "run the command in sys.argv"
27 sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
27 sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
28
28
29 def dispatch(req):
29 def dispatch(req):
30 "run the command specified in req.args"
30 "run the command specified in req.args"
31 if req.ferr:
31 if req.ferr:
32 ferr = req.ferr
32 ferr = req.ferr
33 elif req.ui:
33 elif req.ui:
34 ferr = req.ui.ferr
34 ferr = req.ui.ferr
35 else:
35 else:
36 ferr = sys.stderr
36 ferr = sys.stderr
37
37
38 try:
38 try:
39 if not req.ui:
39 if not req.ui:
40 req.ui = uimod.ui()
40 req.ui = uimod.ui()
41 if '--traceback' in req.args:
41 if '--traceback' in req.args:
42 req.ui.setconfig('ui', 'traceback', 'on')
42 req.ui.setconfig('ui', 'traceback', 'on')
43
43
44 # set ui streams from the request
44 # set ui streams from the request
45 if req.fin:
45 if req.fin:
46 req.ui.fin = req.fin
46 req.ui.fin = req.fin
47 if req.fout:
47 if req.fout:
48 req.ui.fout = req.fout
48 req.ui.fout = req.fout
49 if req.ferr:
49 if req.ferr:
50 req.ui.ferr = req.ferr
50 req.ui.ferr = req.ferr
51 except util.Abort, inst:
51 except util.Abort, inst:
52 ferr.write(_("abort: %s\n") % inst)
52 ferr.write(_("abort: %s\n") % inst)
53 if inst.hint:
53 if inst.hint:
54 ferr.write(_("(%s)\n") % inst.hint)
54 ferr.write(_("(%s)\n") % inst.hint)
55 return -1
55 return -1
56 except error.ParseError, inst:
56 except error.ParseError, inst:
57 if len(inst.args) > 1:
57 if len(inst.args) > 1:
58 ferr.write(_("hg: parse error at %s: %s\n") %
58 ferr.write(_("hg: parse error at %s: %s\n") %
59 (inst.args[1], inst.args[0]))
59 (inst.args[1], inst.args[0]))
60 else:
60 else:
61 ferr.write(_("hg: parse error: %s\n") % inst.args[0])
61 ferr.write(_("hg: parse error: %s\n") % inst.args[0])
62 return -1
62 return -1
63
63
64 return _runcatch(req)
64 return _runcatch(req)
65
65
66 def _runcatch(req):
66 def _runcatch(req):
67 def catchterm(*args):
67 def catchterm(*args):
68 raise error.SignalInterrupt
68 raise error.SignalInterrupt
69
69
70 ui = req.ui
70 ui = req.ui
71 try:
71 try:
72 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
72 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
73 num = getattr(signal, name, None)
73 num = getattr(signal, name, None)
74 if num:
74 if num:
75 signal.signal(num, catchterm)
75 signal.signal(num, catchterm)
76 except ValueError:
76 except ValueError:
77 pass # happens if called in a thread
77 pass # happens if called in a thread
78
78
79 try:
79 try:
80 try:
80 try:
81 # enter the debugger before command execution
81 # enter the debugger before command execution
82 if '--debugger' in req.args:
82 if '--debugger' in req.args:
83 ui.warn(_("entering debugger - "
83 ui.warn(_("entering debugger - "
84 "type c to continue starting hg or h for help\n"))
84 "type c to continue starting hg or h for help\n"))
85 pdb.set_trace()
85 pdb.set_trace()
86 try:
86 try:
87 return _dispatch(req)
87 return _dispatch(req)
88 finally:
88 finally:
89 ui.flush()
89 ui.flush()
90 except:
90 except:
91 # enter the debugger when we hit an exception
91 # enter the debugger when we hit an exception
92 if '--debugger' in req.args:
92 if '--debugger' in req.args:
93 traceback.print_exc()
93 traceback.print_exc()
94 pdb.post_mortem(sys.exc_info()[2])
94 pdb.post_mortem(sys.exc_info()[2])
95 ui.traceback()
95 ui.traceback()
96 raise
96 raise
97
97
98 # Global exception handling, alphabetically
98 # Global exception handling, alphabetically
99 # Mercurial-specific first, followed by built-in and library exceptions
99 # Mercurial-specific first, followed by built-in and library exceptions
100 except error.AmbiguousCommand, inst:
100 except error.AmbiguousCommand, inst:
101 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
101 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
102 (inst.args[0], " ".join(inst.args[1])))
102 (inst.args[0], " ".join(inst.args[1])))
103 except error.ParseError, inst:
103 except error.ParseError, inst:
104 if len(inst.args) > 1:
104 if len(inst.args) > 1:
105 ui.warn(_("hg: parse error at %s: %s\n") %
105 ui.warn(_("hg: parse error at %s: %s\n") %
106 (inst.args[1], inst.args[0]))
106 (inst.args[1], inst.args[0]))
107 else:
107 else:
108 ui.warn(_("hg: parse error: %s\n") % inst.args[0])
108 ui.warn(_("hg: parse error: %s\n") % inst.args[0])
109 return -1
109 return -1
110 except error.LockHeld, inst:
110 except error.LockHeld, inst:
111 if inst.errno == errno.ETIMEDOUT:
111 if inst.errno == errno.ETIMEDOUT:
112 reason = _('timed out waiting for lock held by %s') % inst.locker
112 reason = _('timed out waiting for lock held by %s') % inst.locker
113 else:
113 else:
114 reason = _('lock held by %s') % inst.locker
114 reason = _('lock held by %s') % inst.locker
115 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
115 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
116 except error.LockUnavailable, inst:
116 except error.LockUnavailable, inst:
117 ui.warn(_("abort: could not lock %s: %s\n") %
117 ui.warn(_("abort: could not lock %s: %s\n") %
118 (inst.desc or inst.filename, inst.strerror))
118 (inst.desc or inst.filename, inst.strerror))
119 except error.CommandError, inst:
119 except error.CommandError, inst:
120 if inst.args[0]:
120 if inst.args[0]:
121 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
121 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
122 commands.help_(ui, inst.args[0], full=False, command=True)
122 commands.help_(ui, inst.args[0], full=False, command=True)
123 else:
123 else:
124 ui.warn(_("hg: %s\n") % inst.args[1])
124 ui.warn(_("hg: %s\n") % inst.args[1])
125 commands.help_(ui, 'shortlist')
125 commands.help_(ui, 'shortlist')
126 except error.OutOfBandError, inst:
126 except error.OutOfBandError, inst:
127 ui.warn(_("abort: remote error:\n"))
127 ui.warn(_("abort: remote error:\n"))
128 ui.warn(''.join(inst.args))
128 ui.warn(''.join(inst.args))
129 except error.RepoError, inst:
129 except error.RepoError, inst:
130 ui.warn(_("abort: %s!\n") % inst)
130 ui.warn(_("abort: %s!\n") % inst)
131 if inst.hint:
131 if inst.hint:
132 ui.warn(_("(%s)\n") % inst.hint)
132 ui.warn(_("(%s)\n") % inst.hint)
133 except error.ResponseError, inst:
133 except error.ResponseError, inst:
134 ui.warn(_("abort: %s") % inst.args[0])
134 ui.warn(_("abort: %s") % inst.args[0])
135 if not isinstance(inst.args[1], basestring):
135 if not isinstance(inst.args[1], basestring):
136 ui.warn(" %r\n" % (inst.args[1],))
136 ui.warn(" %r\n" % (inst.args[1],))
137 elif not inst.args[1]:
137 elif not inst.args[1]:
138 ui.warn(_(" empty string\n"))
138 ui.warn(_(" empty string\n"))
139 else:
139 else:
140 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
140 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
141 except error.RevlogError, inst:
141 except error.RevlogError, inst:
142 ui.warn(_("abort: %s!\n") % inst)
142 ui.warn(_("abort: %s!\n") % inst)
143 except error.SignalInterrupt:
143 except error.SignalInterrupt:
144 ui.warn(_("killed!\n"))
144 ui.warn(_("killed!\n"))
145 except error.UnknownCommand, inst:
145 except error.UnknownCommand, inst:
146 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
146 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
147 try:
147 try:
148 # check if the command is in a disabled extension
148 # check if the command is in a disabled extension
149 # (but don't check for extensions themselves)
149 # (but don't check for extensions themselves)
150 commands.help_(ui, inst.args[0], unknowncmd=True)
150 commands.help_(ui, inst.args[0], unknowncmd=True)
151 except error.UnknownCommand:
151 except error.UnknownCommand:
152 commands.help_(ui, 'shortlist')
152 commands.help_(ui, 'shortlist')
153 except util.Abort, inst:
153 except util.Abort, inst:
154 ui.warn(_("abort: %s\n") % inst)
154 ui.warn(_("abort: %s\n") % inst)
155 if inst.hint:
155 if inst.hint:
156 ui.warn(_("(%s)\n") % inst.hint)
156 ui.warn(_("(%s)\n") % inst.hint)
157 except ImportError, inst:
157 except ImportError, inst:
158 ui.warn(_("abort: %s!\n") % inst)
158 ui.warn(_("abort: %s!\n") % inst)
159 m = str(inst).split()[-1]
159 m = str(inst).split()[-1]
160 if m in "mpatch bdiff".split():
160 if m in "mpatch bdiff".split():
161 ui.warn(_("(did you forget to compile extensions?)\n"))
161 ui.warn(_("(did you forget to compile extensions?)\n"))
162 elif m in "zlib".split():
162 elif m in "zlib".split():
163 ui.warn(_("(is your Python install correct?)\n"))
163 ui.warn(_("(is your Python install correct?)\n"))
164 except IOError, inst:
164 except IOError, inst:
165 if util.safehasattr(inst, "code"):
165 if util.safehasattr(inst, "code"):
166 ui.warn(_("abort: %s\n") % inst)
166 ui.warn(_("abort: %s\n") % inst)
167 elif util.safehasattr(inst, "reason"):
167 elif util.safehasattr(inst, "reason"):
168 try: # usually it is in the form (errno, strerror)
168 try: # usually it is in the form (errno, strerror)
169 reason = inst.reason.args[1]
169 reason = inst.reason.args[1]
170 except (AttributeError, IndexError):
170 except (AttributeError, IndexError):
171 # it might be anything, for example a string
171 # it might be anything, for example a string
172 reason = inst.reason
172 reason = inst.reason
173 ui.warn(_("abort: error: %s\n") % reason)
173 ui.warn(_("abort: error: %s\n") % reason)
174 elif util.safehasattr(inst, "args") and inst.args[0] == errno.EPIPE:
174 elif util.safehasattr(inst, "args") and inst.args[0] == errno.EPIPE:
175 if ui.debugflag:
175 if ui.debugflag:
176 ui.warn(_("broken pipe\n"))
176 ui.warn(_("broken pipe\n"))
177 elif getattr(inst, "strerror", None):
177 elif getattr(inst, "strerror", None):
178 if getattr(inst, "filename", None):
178 if getattr(inst, "filename", None):
179 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
179 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
180 else:
180 else:
181 ui.warn(_("abort: %s\n") % inst.strerror)
181 ui.warn(_("abort: %s\n") % inst.strerror)
182 else:
182 else:
183 raise
183 raise
184 except OSError, inst:
184 except OSError, inst:
185 if getattr(inst, "filename", None):
185 if getattr(inst, "filename", None):
186 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
186 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
187 else:
187 else:
188 ui.warn(_("abort: %s\n") % inst.strerror)
188 ui.warn(_("abort: %s\n") % inst.strerror)
189 except KeyboardInterrupt:
189 except KeyboardInterrupt:
190 try:
190 try:
191 ui.warn(_("interrupted!\n"))
191 ui.warn(_("interrupted!\n"))
192 except IOError, inst:
192 except IOError, inst:
193 if inst.errno == errno.EPIPE:
193 if inst.errno == errno.EPIPE:
194 if ui.debugflag:
194 if ui.debugflag:
195 ui.warn(_("\nbroken pipe\n"))
195 ui.warn(_("\nbroken pipe\n"))
196 else:
196 else:
197 raise
197 raise
198 except MemoryError:
198 except MemoryError:
199 ui.warn(_("abort: out of memory\n"))
199 ui.warn(_("abort: out of memory\n"))
200 except SystemExit, inst:
200 except SystemExit, inst:
201 # Commands shouldn't sys.exit directly, but give a return code.
201 # Commands shouldn't sys.exit directly, but give a return code.
202 # Just in case catch this and and pass exit code to caller.
202 # Just in case catch this and and pass exit code to caller.
203 return inst.code
203 return inst.code
204 except socket.error, inst:
204 except socket.error, inst:
205 ui.warn(_("abort: %s\n") % inst.args[-1])
205 ui.warn(_("abort: %s\n") % inst.args[-1])
206 except:
206 except:
207 ui.warn(_("** unknown exception encountered,"
207 ui.warn(_("** unknown exception encountered,"
208 " please report by visiting\n"))
208 " please report by visiting\n"))
209 ui.warn(_("** http://mercurial.selenic.com/wiki/BugTracker\n"))
209 ui.warn(_("** http://mercurial.selenic.com/wiki/BugTracker\n"))
210 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
210 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
211 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
211 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
212 % util.version())
212 % util.version())
213 ui.warn(_("** Extensions loaded: %s\n")
213 ui.warn(_("** Extensions loaded: %s\n")
214 % ", ".join([x[0] for x in extensions.extensions()]))
214 % ", ".join([x[0] for x in extensions.extensions()]))
215 raise
215 raise
216
216
217 return -1
217 return -1
218
218
219 def aliasargs(fn, givenargs):
219 def aliasargs(fn, givenargs):
220 args = getattr(fn, 'args', [])
220 args = getattr(fn, 'args', [])
221 if args:
221 if args:
222 cmd = ' '.join(map(util.shellquote, args))
222 cmd = ' '.join(map(util.shellquote, args))
223
223
224 nums = []
224 nums = []
225 def replacer(m):
225 def replacer(m):
226 num = int(m.group(1)) - 1
226 num = int(m.group(1)) - 1
227 nums.append(num)
227 nums.append(num)
228 if num < len(givenargs):
228 if num < len(givenargs):
229 return givenargs[num]
229 return givenargs[num]
230 raise util.Abort(_('too few arguments for command alias'))
230 raise util.Abort(_('too few arguments for command alias'))
231 cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
231 cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
232 givenargs = [x for i, x in enumerate(givenargs)
232 givenargs = [x for i, x in enumerate(givenargs)
233 if i not in nums]
233 if i not in nums]
234 args = shlex.split(cmd)
234 args = shlex.split(cmd)
235 return args + givenargs
235 return args + givenargs
236
236
237 class cmdalias(object):
237 class cmdalias(object):
238 def __init__(self, name, definition, cmdtable):
238 def __init__(self, name, definition, cmdtable):
239 self.name = self.cmd = name
239 self.name = self.cmd = name
240 self.cmdname = ''
240 self.cmdname = ''
241 self.definition = definition
241 self.definition = definition
242 self.args = []
242 self.args = []
243 self.opts = []
243 self.opts = []
244 self.help = ''
244 self.help = ''
245 self.norepo = True
245 self.norepo = True
246 self.optionalrepo = False
246 self.badalias = False
247 self.badalias = False
247
248
248 try:
249 try:
249 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
250 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
250 for alias, e in cmdtable.iteritems():
251 for alias, e in cmdtable.iteritems():
251 if e is entry:
252 if e is entry:
252 self.cmd = alias
253 self.cmd = alias
253 break
254 break
254 self.shadows = True
255 self.shadows = True
255 except error.UnknownCommand:
256 except error.UnknownCommand:
256 self.shadows = False
257 self.shadows = False
257
258
258 if not self.definition:
259 if not self.definition:
259 def fn(ui, *args):
260 def fn(ui, *args):
260 ui.warn(_("no definition for alias '%s'\n") % self.name)
261 ui.warn(_("no definition for alias '%s'\n") % self.name)
261 return 1
262 return 1
262 self.fn = fn
263 self.fn = fn
263 self.badalias = True
264 self.badalias = True
264 return
265 return
265
266
266 if self.definition.startswith('!'):
267 if self.definition.startswith('!'):
267 self.shell = True
268 self.shell = True
268 def fn(ui, *args):
269 def fn(ui, *args):
269 env = {'HG_ARGS': ' '.join((self.name,) + args)}
270 env = {'HG_ARGS': ' '.join((self.name,) + args)}
270 def _checkvar(m):
271 def _checkvar(m):
271 if m.groups()[0] == '$':
272 if m.groups()[0] == '$':
272 return m.group()
273 return m.group()
273 elif int(m.groups()[0]) <= len(args):
274 elif int(m.groups()[0]) <= len(args):
274 return m.group()
275 return m.group()
275 else:
276 else:
276 ui.debug("No argument found for substitution "
277 ui.debug("No argument found for substitution "
277 "of %i variable in alias '%s' definition."
278 "of %i variable in alias '%s' definition."
278 % (int(m.groups()[0]), self.name))
279 % (int(m.groups()[0]), self.name))
279 return ''
280 return ''
280 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
281 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
281 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
282 replace = dict((str(i + 1), arg) for i, arg in enumerate(args))
282 replace['0'] = self.name
283 replace['0'] = self.name
283 replace['@'] = ' '.join(args)
284 replace['@'] = ' '.join(args)
284 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
285 cmd = util.interpolate(r'\$', replace, cmd, escape_prefix=True)
285 return util.system(cmd, environ=env, out=ui.fout)
286 return util.system(cmd, environ=env, out=ui.fout)
286 self.fn = fn
287 self.fn = fn
287 return
288 return
288
289
289 args = shlex.split(self.definition)
290 args = shlex.split(self.definition)
290 self.cmdname = cmd = args.pop(0)
291 self.cmdname = cmd = args.pop(0)
291 args = map(util.expandpath, args)
292 args = map(util.expandpath, args)
292
293
293 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
294 for invalidarg in ("--cwd", "-R", "--repository", "--repo"):
294 if _earlygetopt([invalidarg], args):
295 if _earlygetopt([invalidarg], args):
295 def fn(ui, *args):
296 def fn(ui, *args):
296 ui.warn(_("error in definition for alias '%s': %s may only "
297 ui.warn(_("error in definition for alias '%s': %s may only "
297 "be given on the command line\n")
298 "be given on the command line\n")
298 % (self.name, invalidarg))
299 % (self.name, invalidarg))
299 return 1
300 return 1
300
301
301 self.fn = fn
302 self.fn = fn
302 self.badalias = True
303 self.badalias = True
303 return
304 return
304
305
305 try:
306 try:
306 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
307 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
307 if len(tableentry) > 2:
308 if len(tableentry) > 2:
308 self.fn, self.opts, self.help = tableentry
309 self.fn, self.opts, self.help = tableentry
309 else:
310 else:
310 self.fn, self.opts = tableentry
311 self.fn, self.opts = tableentry
311
312
312 self.args = aliasargs(self.fn, args)
313 self.args = aliasargs(self.fn, args)
313 if cmd not in commands.norepo.split(' '):
314 if cmd not in commands.norepo.split(' '):
314 self.norepo = False
315 self.norepo = False
316 if cmd in commands.optionalrepo.split(' '):
317 self.optionalrepo = True
315 if self.help.startswith("hg " + cmd):
318 if self.help.startswith("hg " + cmd):
316 # drop prefix in old-style help lines so hg shows the alias
319 # drop prefix in old-style help lines so hg shows the alias
317 self.help = self.help[4 + len(cmd):]
320 self.help = self.help[4 + len(cmd):]
318 self.__doc__ = self.fn.__doc__
321 self.__doc__ = self.fn.__doc__
319
322
320 except error.UnknownCommand:
323 except error.UnknownCommand:
321 def fn(ui, *args):
324 def fn(ui, *args):
322 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
325 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
323 % (self.name, cmd))
326 % (self.name, cmd))
324 try:
327 try:
325 # check if the command is in a disabled extension
328 # check if the command is in a disabled extension
326 commands.help_(ui, cmd, unknowncmd=True)
329 commands.help_(ui, cmd, unknowncmd=True)
327 except error.UnknownCommand:
330 except error.UnknownCommand:
328 pass
331 pass
329 return 1
332 return 1
330 self.fn = fn
333 self.fn = fn
331 self.badalias = True
334 self.badalias = True
332 except error.AmbiguousCommand:
335 except error.AmbiguousCommand:
333 def fn(ui, *args):
336 def fn(ui, *args):
334 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
337 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
335 % (self.name, cmd))
338 % (self.name, cmd))
336 return 1
339 return 1
337 self.fn = fn
340 self.fn = fn
338 self.badalias = True
341 self.badalias = True
339
342
340 def __call__(self, ui, *args, **opts):
343 def __call__(self, ui, *args, **opts):
341 if self.shadows:
344 if self.shadows:
342 ui.debug("alias '%s' shadows command '%s'\n" %
345 ui.debug("alias '%s' shadows command '%s'\n" %
343 (self.name, self.cmdname))
346 (self.name, self.cmdname))
344
347
345 if util.safehasattr(self, 'shell'):
348 if util.safehasattr(self, 'shell'):
346 return self.fn(ui, *args, **opts)
349 return self.fn(ui, *args, **opts)
347 else:
350 else:
348 try:
351 try:
349 util.checksignature(self.fn)(ui, *args, **opts)
352 util.checksignature(self.fn)(ui, *args, **opts)
350 except error.SignatureError:
353 except error.SignatureError:
351 args = ' '.join([self.cmdname] + self.args)
354 args = ' '.join([self.cmdname] + self.args)
352 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
355 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
353 raise
356 raise
354
357
355 def addaliases(ui, cmdtable):
358 def addaliases(ui, cmdtable):
356 # aliases are processed after extensions have been loaded, so they
359 # aliases are processed after extensions have been loaded, so they
357 # may use extension commands. Aliases can also use other alias definitions,
360 # may use extension commands. Aliases can also use other alias definitions,
358 # but only if they have been defined prior to the current definition.
361 # but only if they have been defined prior to the current definition.
359 for alias, definition in ui.configitems('alias'):
362 for alias, definition in ui.configitems('alias'):
360 aliasdef = cmdalias(alias, definition, cmdtable)
363 aliasdef = cmdalias(alias, definition, cmdtable)
361
364
362 try:
365 try:
363 olddef = cmdtable[aliasdef.cmd][0]
366 olddef = cmdtable[aliasdef.cmd][0]
364 if olddef.definition == aliasdef.definition:
367 if olddef.definition == aliasdef.definition:
365 continue
368 continue
366 except (KeyError, AttributeError):
369 except (KeyError, AttributeError):
367 # definition might not exist or it might not be a cmdalias
370 # definition might not exist or it might not be a cmdalias
368 pass
371 pass
369
372
370 cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
373 cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
371 if aliasdef.norepo:
374 if aliasdef.norepo:
372 commands.norepo += ' %s' % alias
375 commands.norepo += ' %s' % alias
376 if aliasdef.optionalrepo:
377 commands.optionalrepo += ' %s' % alias
373
378
374 def _parse(ui, args):
379 def _parse(ui, args):
375 options = {}
380 options = {}
376 cmdoptions = {}
381 cmdoptions = {}
377
382
378 try:
383 try:
379 args = fancyopts.fancyopts(args, commands.globalopts, options)
384 args = fancyopts.fancyopts(args, commands.globalopts, options)
380 except fancyopts.getopt.GetoptError, inst:
385 except fancyopts.getopt.GetoptError, inst:
381 raise error.CommandError(None, inst)
386 raise error.CommandError(None, inst)
382
387
383 if args:
388 if args:
384 cmd, args = args[0], args[1:]
389 cmd, args = args[0], args[1:]
385 aliases, entry = cmdutil.findcmd(cmd, commands.table,
390 aliases, entry = cmdutil.findcmd(cmd, commands.table,
386 ui.configbool("ui", "strict"))
391 ui.configbool("ui", "strict"))
387 cmd = aliases[0]
392 cmd = aliases[0]
388 args = aliasargs(entry[0], args)
393 args = aliasargs(entry[0], args)
389 defaults = ui.config("defaults", cmd)
394 defaults = ui.config("defaults", cmd)
390 if defaults:
395 if defaults:
391 args = map(util.expandpath, shlex.split(defaults)) + args
396 args = map(util.expandpath, shlex.split(defaults)) + args
392 c = list(entry[1])
397 c = list(entry[1])
393 else:
398 else:
394 cmd = None
399 cmd = None
395 c = []
400 c = []
396
401
397 # combine global options into local
402 # combine global options into local
398 for o in commands.globalopts:
403 for o in commands.globalopts:
399 c.append((o[0], o[1], options[o[1]], o[3]))
404 c.append((o[0], o[1], options[o[1]], o[3]))
400
405
401 try:
406 try:
402 args = fancyopts.fancyopts(args, c, cmdoptions, True)
407 args = fancyopts.fancyopts(args, c, cmdoptions, True)
403 except fancyopts.getopt.GetoptError, inst:
408 except fancyopts.getopt.GetoptError, inst:
404 raise error.CommandError(cmd, inst)
409 raise error.CommandError(cmd, inst)
405
410
406 # separate global options back out
411 # separate global options back out
407 for o in commands.globalopts:
412 for o in commands.globalopts:
408 n = o[1]
413 n = o[1]
409 options[n] = cmdoptions[n]
414 options[n] = cmdoptions[n]
410 del cmdoptions[n]
415 del cmdoptions[n]
411
416
412 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
417 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
413
418
414 def _parseconfig(ui, config):
419 def _parseconfig(ui, config):
415 """parse the --config options from the command line"""
420 """parse the --config options from the command line"""
416 configs = []
421 configs = []
417
422
418 for cfg in config:
423 for cfg in config:
419 try:
424 try:
420 name, value = cfg.split('=', 1)
425 name, value = cfg.split('=', 1)
421 section, name = name.split('.', 1)
426 section, name = name.split('.', 1)
422 if not section or not name:
427 if not section or not name:
423 raise IndexError
428 raise IndexError
424 ui.setconfig(section, name, value)
429 ui.setconfig(section, name, value)
425 configs.append((section, name, value))
430 configs.append((section, name, value))
426 except (IndexError, ValueError):
431 except (IndexError, ValueError):
427 raise util.Abort(_('malformed --config option: %r '
432 raise util.Abort(_('malformed --config option: %r '
428 '(use --config section.name=value)') % cfg)
433 '(use --config section.name=value)') % cfg)
429
434
430 return configs
435 return configs
431
436
432 def _earlygetopt(aliases, args):
437 def _earlygetopt(aliases, args):
433 """Return list of values for an option (or aliases).
438 """Return list of values for an option (or aliases).
434
439
435 The values are listed in the order they appear in args.
440 The values are listed in the order they appear in args.
436 The options and values are removed from args.
441 The options and values are removed from args.
437 """
442 """
438 try:
443 try:
439 argcount = args.index("--")
444 argcount = args.index("--")
440 except ValueError:
445 except ValueError:
441 argcount = len(args)
446 argcount = len(args)
442 shortopts = [opt for opt in aliases if len(opt) == 2]
447 shortopts = [opt for opt in aliases if len(opt) == 2]
443 values = []
448 values = []
444 pos = 0
449 pos = 0
445 while pos < argcount:
450 while pos < argcount:
446 if args[pos] in aliases:
451 if args[pos] in aliases:
447 if pos + 1 >= argcount:
452 if pos + 1 >= argcount:
448 # ignore and let getopt report an error if there is no value
453 # ignore and let getopt report an error if there is no value
449 break
454 break
450 del args[pos]
455 del args[pos]
451 values.append(args.pop(pos))
456 values.append(args.pop(pos))
452 argcount -= 2
457 argcount -= 2
453 elif args[pos][:2] in shortopts:
458 elif args[pos][:2] in shortopts:
454 # short option can have no following space, e.g. hg log -Rfoo
459 # short option can have no following space, e.g. hg log -Rfoo
455 values.append(args.pop(pos)[2:])
460 values.append(args.pop(pos)[2:])
456 argcount -= 1
461 argcount -= 1
457 else:
462 else:
458 pos += 1
463 pos += 1
459 return values
464 return values
460
465
461 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
466 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
462 # run pre-hook, and abort if it fails
467 # run pre-hook, and abort if it fails
463 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
468 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs),
464 pats=cmdpats, opts=cmdoptions)
469 pats=cmdpats, opts=cmdoptions)
465 if ret:
470 if ret:
466 return ret
471 return ret
467 ret = _runcommand(ui, options, cmd, d)
472 ret = _runcommand(ui, options, cmd, d)
468 # run post-hook, passing command result
473 # run post-hook, passing command result
469 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
474 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
470 result=ret, pats=cmdpats, opts=cmdoptions)
475 result=ret, pats=cmdpats, opts=cmdoptions)
471 return ret
476 return ret
472
477
473 def _getlocal(ui, rpath):
478 def _getlocal(ui, rpath):
474 """Return (path, local ui object) for the given target path.
479 """Return (path, local ui object) for the given target path.
475
480
476 Takes paths in [cwd]/.hg/hgrc into account."
481 Takes paths in [cwd]/.hg/hgrc into account."
477 """
482 """
478 try:
483 try:
479 wd = os.getcwd()
484 wd = os.getcwd()
480 except OSError, e:
485 except OSError, e:
481 raise util.Abort(_("error getting current working directory: %s") %
486 raise util.Abort(_("error getting current working directory: %s") %
482 e.strerror)
487 e.strerror)
483 path = cmdutil.findrepo(wd) or ""
488 path = cmdutil.findrepo(wd) or ""
484 if not path:
489 if not path:
485 lui = ui
490 lui = ui
486 else:
491 else:
487 lui = ui.copy()
492 lui = ui.copy()
488 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
493 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
489
494
490 if rpath and rpath[-1]:
495 if rpath and rpath[-1]:
491 path = lui.expandpath(rpath[-1])
496 path = lui.expandpath(rpath[-1])
492 lui = ui.copy()
497 lui = ui.copy()
493 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
498 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
494
499
495 return path, lui
500 return path, lui
496
501
497 def _checkshellalias(lui, ui, args):
502 def _checkshellalias(lui, ui, args):
498 norepo = commands.norepo
499 options = {}
503 options = {}
500
504
501 try:
505 try:
502 args = fancyopts.fancyopts(args, commands.globalopts, options)
506 args = fancyopts.fancyopts(args, commands.globalopts, options)
503 except fancyopts.getopt.GetoptError:
507 except fancyopts.getopt.GetoptError:
504 return
508 return
505
509
506 if not args:
510 if not args:
507 return
511 return
508
512
513 norepo = commands.norepo
514 optionalrepo = commands.optionalrepo
515 def restorecommands():
516 commands.norepo = norepo
517 commands.optionalrepo = optionalrepo
518
509 cmdtable = commands.table.copy()
519 cmdtable = commands.table.copy()
510 addaliases(lui, cmdtable)
520 addaliases(lui, cmdtable)
511
521
512 cmd = args[0]
522 cmd = args[0]
513 try:
523 try:
514 aliases, entry = cmdutil.findcmd(cmd, cmdtable,
524 aliases, entry = cmdutil.findcmd(cmd, cmdtable,
515 lui.configbool("ui", "strict"))
525 lui.configbool("ui", "strict"))
516 except (error.AmbiguousCommand, error.UnknownCommand):
526 except (error.AmbiguousCommand, error.UnknownCommand):
517 commands.norepo = norepo
527 restorecommands()
518 return
528 return
519
529
520 cmd = aliases[0]
530 cmd = aliases[0]
521 fn = entry[0]
531 fn = entry[0]
522
532
523 if cmd and util.safehasattr(fn, 'shell'):
533 if cmd and util.safehasattr(fn, 'shell'):
524 d = lambda: fn(ui, *args[1:])
534 d = lambda: fn(ui, *args[1:])
525 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
535 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {})
526
536
527 commands.norepo = norepo
537 restorecommands()
528
538
529 _loaded = set()
539 _loaded = set()
530 def _dispatch(req):
540 def _dispatch(req):
531 args = req.args
541 args = req.args
532 ui = req.ui
542 ui = req.ui
533
543
534 # read --config before doing anything else
544 # read --config before doing anything else
535 # (e.g. to change trust settings for reading .hg/hgrc)
545 # (e.g. to change trust settings for reading .hg/hgrc)
536 cfgs = _parseconfig(ui, _earlygetopt(['--config'], args))
546 cfgs = _parseconfig(ui, _earlygetopt(['--config'], args))
537
547
538 # check for cwd
548 # check for cwd
539 cwd = _earlygetopt(['--cwd'], args)
549 cwd = _earlygetopt(['--cwd'], args)
540 if cwd:
550 if cwd:
541 os.chdir(cwd[-1])
551 os.chdir(cwd[-1])
542
552
543 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
553 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
544 path, lui = _getlocal(ui, rpath)
554 path, lui = _getlocal(ui, rpath)
545
555
546 # Now that we're operating in the right directory/repository with
556 # Now that we're operating in the right directory/repository with
547 # the right config settings, check for shell aliases
557 # the right config settings, check for shell aliases
548 shellaliasfn = _checkshellalias(lui, ui, args)
558 shellaliasfn = _checkshellalias(lui, ui, args)
549 if shellaliasfn:
559 if shellaliasfn:
550 return shellaliasfn()
560 return shellaliasfn()
551
561
552 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
562 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
553 # reposetup. Programs like TortoiseHg will call _dispatch several
563 # reposetup. Programs like TortoiseHg will call _dispatch several
554 # times so we keep track of configured extensions in _loaded.
564 # times so we keep track of configured extensions in _loaded.
555 extensions.loadall(lui)
565 extensions.loadall(lui)
556 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
566 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
557 # Propagate any changes to lui.__class__ by extensions
567 # Propagate any changes to lui.__class__ by extensions
558 ui.__class__ = lui.__class__
568 ui.__class__ = lui.__class__
559
569
560 # (uisetup and extsetup are handled in extensions.loadall)
570 # (uisetup and extsetup are handled in extensions.loadall)
561
571
562 for name, module in exts:
572 for name, module in exts:
563 cmdtable = getattr(module, 'cmdtable', {})
573 cmdtable = getattr(module, 'cmdtable', {})
564 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
574 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
565 if overrides:
575 if overrides:
566 ui.warn(_("extension '%s' overrides commands: %s\n")
576 ui.warn(_("extension '%s' overrides commands: %s\n")
567 % (name, " ".join(overrides)))
577 % (name, " ".join(overrides)))
568 commands.table.update(cmdtable)
578 commands.table.update(cmdtable)
569 _loaded.add(name)
579 _loaded.add(name)
570
580
571 # (reposetup is handled in hg.repository)
581 # (reposetup is handled in hg.repository)
572
582
573 addaliases(lui, commands.table)
583 addaliases(lui, commands.table)
574
584
575 # check for fallback encoding
585 # check for fallback encoding
576 fallback = lui.config('ui', 'fallbackencoding')
586 fallback = lui.config('ui', 'fallbackencoding')
577 if fallback:
587 if fallback:
578 encoding.fallbackencoding = fallback
588 encoding.fallbackencoding = fallback
579
589
580 fullargs = args
590 fullargs = args
581 cmd, func, args, options, cmdoptions = _parse(lui, args)
591 cmd, func, args, options, cmdoptions = _parse(lui, args)
582
592
583 if options["config"]:
593 if options["config"]:
584 raise util.Abort(_("option --config may not be abbreviated!"))
594 raise util.Abort(_("option --config may not be abbreviated!"))
585 if options["cwd"]:
595 if options["cwd"]:
586 raise util.Abort(_("option --cwd may not be abbreviated!"))
596 raise util.Abort(_("option --cwd may not be abbreviated!"))
587 if options["repository"]:
597 if options["repository"]:
588 raise util.Abort(_(
598 raise util.Abort(_(
589 "option -R has to be separated from other options (e.g. not -qR) "
599 "option -R has to be separated from other options (e.g. not -qR) "
590 "and --repository may only be abbreviated as --repo!"))
600 "and --repository may only be abbreviated as --repo!"))
591
601
592 if options["encoding"]:
602 if options["encoding"]:
593 encoding.encoding = options["encoding"]
603 encoding.encoding = options["encoding"]
594 if options["encodingmode"]:
604 if options["encodingmode"]:
595 encoding.encodingmode = options["encodingmode"]
605 encoding.encodingmode = options["encodingmode"]
596 if options["time"]:
606 if options["time"]:
597 def get_times():
607 def get_times():
598 t = os.times()
608 t = os.times()
599 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
609 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
600 t = (t[0], t[1], t[2], t[3], time.clock())
610 t = (t[0], t[1], t[2], t[3], time.clock())
601 return t
611 return t
602 s = get_times()
612 s = get_times()
603 def print_time():
613 def print_time():
604 t = get_times()
614 t = get_times()
605 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
615 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
606 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
616 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
607 atexit.register(print_time)
617 atexit.register(print_time)
608
618
609 uis = set([ui, lui])
619 uis = set([ui, lui])
610
620
611 if req.repo:
621 if req.repo:
612 uis.add(req.repo.ui)
622 uis.add(req.repo.ui)
613
623
614 # copy configs that were passed on the cmdline (--config) to the repo ui
624 # copy configs that were passed on the cmdline (--config) to the repo ui
615 for cfg in cfgs:
625 for cfg in cfgs:
616 req.repo.ui.setconfig(*cfg)
626 req.repo.ui.setconfig(*cfg)
617
627
618 if options['verbose'] or options['debug'] or options['quiet']:
628 if options['verbose'] or options['debug'] or options['quiet']:
619 for opt in ('verbose', 'debug', 'quiet'):
629 for opt in ('verbose', 'debug', 'quiet'):
620 val = str(bool(options[opt]))
630 val = str(bool(options[opt]))
621 for ui_ in uis:
631 for ui_ in uis:
622 ui_.setconfig('ui', opt, val)
632 ui_.setconfig('ui', opt, val)
623
633
624 if options['traceback']:
634 if options['traceback']:
625 for ui_ in uis:
635 for ui_ in uis:
626 ui_.setconfig('ui', 'traceback', 'on')
636 ui_.setconfig('ui', 'traceback', 'on')
627
637
628 if options['noninteractive']:
638 if options['noninteractive']:
629 for ui_ in uis:
639 for ui_ in uis:
630 ui_.setconfig('ui', 'interactive', 'off')
640 ui_.setconfig('ui', 'interactive', 'off')
631
641
632 if cmdoptions.get('insecure', False):
642 if cmdoptions.get('insecure', False):
633 for ui_ in uis:
643 for ui_ in uis:
634 ui_.setconfig('web', 'cacerts', '')
644 ui_.setconfig('web', 'cacerts', '')
635
645
636 if options['version']:
646 if options['version']:
637 return commands.version_(ui)
647 return commands.version_(ui)
638 if options['help']:
648 if options['help']:
639 return commands.help_(ui, cmd)
649 return commands.help_(ui, cmd)
640 elif not cmd:
650 elif not cmd:
641 return commands.help_(ui, 'shortlist')
651 return commands.help_(ui, 'shortlist')
642
652
643 repo = None
653 repo = None
644 cmdpats = args[:]
654 cmdpats = args[:]
645 if cmd not in commands.norepo.split():
655 if cmd not in commands.norepo.split():
646 # use the repo from the request only if we don't have -R
656 # use the repo from the request only if we don't have -R
647 if not rpath and not cwd:
657 if not rpath and not cwd:
648 repo = req.repo
658 repo = req.repo
649
659
650 if repo:
660 if repo:
651 # set the descriptors of the repo ui to those of ui
661 # set the descriptors of the repo ui to those of ui
652 repo.ui.fin = ui.fin
662 repo.ui.fin = ui.fin
653 repo.ui.fout = ui.fout
663 repo.ui.fout = ui.fout
654 repo.ui.ferr = ui.ferr
664 repo.ui.ferr = ui.ferr
655 else:
665 else:
656 try:
666 try:
657 repo = hg.repository(ui, path=path)
667 repo = hg.repository(ui, path=path)
658 if not repo.local():
668 if not repo.local():
659 raise util.Abort(_("repository '%s' is not local") % path)
669 raise util.Abort(_("repository '%s' is not local") % path)
660 repo.ui.setconfig("bundle", "mainreporoot", repo.root)
670 repo.ui.setconfig("bundle", "mainreporoot", repo.root)
661 except error.RequirementError:
671 except error.RequirementError:
662 raise
672 raise
663 except error.RepoError:
673 except error.RepoError:
664 if cmd not in commands.optionalrepo.split():
674 if cmd not in commands.optionalrepo.split():
665 if args and not path: # try to infer -R from command args
675 if args and not path: # try to infer -R from command args
666 repos = map(cmdutil.findrepo, args)
676 repos = map(cmdutil.findrepo, args)
667 guess = repos[0]
677 guess = repos[0]
668 if guess and repos.count(guess) == len(repos):
678 if guess and repos.count(guess) == len(repos):
669 req.args = ['--repository', guess] + fullargs
679 req.args = ['--repository', guess] + fullargs
670 return _dispatch(req)
680 return _dispatch(req)
671 if not path:
681 if not path:
672 raise error.RepoError(_("no repository found in '%s'"
682 raise error.RepoError(_("no repository found in '%s'"
673 " (.hg not found)") % os.getcwd())
683 " (.hg not found)") % os.getcwd())
674 raise
684 raise
675 if repo:
685 if repo:
676 ui = repo.ui
686 ui = repo.ui
677 args.insert(0, repo)
687 args.insert(0, repo)
678 elif rpath:
688 elif rpath:
679 ui.warn(_("warning: --repository ignored\n"))
689 ui.warn(_("warning: --repository ignored\n"))
680
690
681 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
691 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
682 ui.log("command", msg + "\n")
692 ui.log("command", msg + "\n")
683 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
693 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
684 try:
694 try:
685 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
695 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
686 cmdpats, cmdoptions)
696 cmdpats, cmdoptions)
687 finally:
697 finally:
688 if repo and repo != req.repo:
698 if repo and repo != req.repo:
689 repo.close()
699 repo.close()
690
700
691 def lsprofile(ui, func, fp):
701 def lsprofile(ui, func, fp):
692 format = ui.config('profiling', 'format', default='text')
702 format = ui.config('profiling', 'format', default='text')
693 field = ui.config('profiling', 'sort', default='inlinetime')
703 field = ui.config('profiling', 'sort', default='inlinetime')
694 climit = ui.configint('profiling', 'nested', default=5)
704 climit = ui.configint('profiling', 'nested', default=5)
695
705
696 if not format in ['text', 'kcachegrind']:
706 if not format in ['text', 'kcachegrind']:
697 ui.warn(_("unrecognized profiling format '%s'"
707 ui.warn(_("unrecognized profiling format '%s'"
698 " - Ignored\n") % format)
708 " - Ignored\n") % format)
699 format = 'text'
709 format = 'text'
700
710
701 try:
711 try:
702 from mercurial import lsprof
712 from mercurial import lsprof
703 except ImportError:
713 except ImportError:
704 raise util.Abort(_(
714 raise util.Abort(_(
705 'lsprof not available - install from '
715 'lsprof not available - install from '
706 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
716 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
707 p = lsprof.Profiler()
717 p = lsprof.Profiler()
708 p.enable(subcalls=True)
718 p.enable(subcalls=True)
709 try:
719 try:
710 return func()
720 return func()
711 finally:
721 finally:
712 p.disable()
722 p.disable()
713
723
714 if format == 'kcachegrind':
724 if format == 'kcachegrind':
715 import lsprofcalltree
725 import lsprofcalltree
716 calltree = lsprofcalltree.KCacheGrind(p)
726 calltree = lsprofcalltree.KCacheGrind(p)
717 calltree.output(fp)
727 calltree.output(fp)
718 else:
728 else:
719 # format == 'text'
729 # format == 'text'
720 stats = lsprof.Stats(p.getstats())
730 stats = lsprof.Stats(p.getstats())
721 stats.sort(field)
731 stats.sort(field)
722 stats.pprint(limit=30, file=fp, climit=climit)
732 stats.pprint(limit=30, file=fp, climit=climit)
723
733
724 def statprofile(ui, func, fp):
734 def statprofile(ui, func, fp):
725 try:
735 try:
726 import statprof
736 import statprof
727 except ImportError:
737 except ImportError:
728 raise util.Abort(_(
738 raise util.Abort(_(
729 'statprof not available - install using "easy_install statprof"'))
739 'statprof not available - install using "easy_install statprof"'))
730
740
731 freq = ui.configint('profiling', 'freq', default=1000)
741 freq = ui.configint('profiling', 'freq', default=1000)
732 if freq > 0:
742 if freq > 0:
733 statprof.reset(freq)
743 statprof.reset(freq)
734 else:
744 else:
735 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
745 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
736
746
737 statprof.start()
747 statprof.start()
738 try:
748 try:
739 return func()
749 return func()
740 finally:
750 finally:
741 statprof.stop()
751 statprof.stop()
742 statprof.display(fp)
752 statprof.display(fp)
743
753
744 def _runcommand(ui, options, cmd, cmdfunc):
754 def _runcommand(ui, options, cmd, cmdfunc):
745 def checkargs():
755 def checkargs():
746 try:
756 try:
747 return cmdfunc()
757 return cmdfunc()
748 except error.SignatureError:
758 except error.SignatureError:
749 raise error.CommandError(cmd, _("invalid arguments"))
759 raise error.CommandError(cmd, _("invalid arguments"))
750
760
751 if options['profile']:
761 if options['profile']:
752 profiler = os.getenv('HGPROF')
762 profiler = os.getenv('HGPROF')
753 if profiler is None:
763 if profiler is None:
754 profiler = ui.config('profiling', 'type', default='ls')
764 profiler = ui.config('profiling', 'type', default='ls')
755 if profiler not in ('ls', 'stat'):
765 if profiler not in ('ls', 'stat'):
756 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler)
766 ui.warn(_("unrecognized profiler '%s' - ignored\n") % profiler)
757 profiler = 'ls'
767 profiler = 'ls'
758
768
759 output = ui.config('profiling', 'output')
769 output = ui.config('profiling', 'output')
760
770
761 if output:
771 if output:
762 path = ui.expandpath(output)
772 path = ui.expandpath(output)
763 fp = open(path, 'wb')
773 fp = open(path, 'wb')
764 else:
774 else:
765 fp = sys.stderr
775 fp = sys.stderr
766
776
767 try:
777 try:
768 if profiler == 'ls':
778 if profiler == 'ls':
769 return lsprofile(ui, checkargs, fp)
779 return lsprofile(ui, checkargs, fp)
770 else:
780 else:
771 return statprofile(ui, checkargs, fp)
781 return statprofile(ui, checkargs, fp)
772 finally:
782 finally:
773 if output:
783 if output:
774 fp.close()
784 fp.close()
775 else:
785 else:
776 return checkargs()
786 return checkargs()
@@ -1,416 +1,426
1 $ "$TESTDIR/hghave" system-sh || exit 80
1 $ "$TESTDIR/hghave" system-sh || exit 80
2
2
3 $ HGFOO=BAR; export HGFOO
3 $ HGFOO=BAR; export HGFOO
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > graphlog=
6 > graphlog=
7 >
7 >
8 > [alias]
8 > [alias]
9 > # should clobber ci but not commit (issue2993)
9 > # should clobber ci but not commit (issue2993)
10 > ci = version
10 > ci = version
11 > myinit = init
11 > myinit = init
12 > optionalrepo = showconfig alias.myinit
12 > cleanstatus = status -c
13 > cleanstatus = status -c
13 > unknown = bargle
14 > unknown = bargle
14 > ambiguous = s
15 > ambiguous = s
15 > recursive = recursive
16 > recursive = recursive
16 > nodefinition =
17 > nodefinition =
17 > no--cwd = status --cwd elsewhere
18 > no--cwd = status --cwd elsewhere
18 > no-R = status -R elsewhere
19 > no-R = status -R elsewhere
19 > no--repo = status --repo elsewhere
20 > no--repo = status --repo elsewhere
20 > no--repository = status --repository elsewhere
21 > no--repository = status --repository elsewhere
21 > mylog = log
22 > mylog = log
22 > lognull = log -r null
23 > lognull = log -r null
23 > shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
24 > shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
24 > positional = log --template '{\$2} {\$1} | {date|isodate}\n'
25 > positional = log --template '{\$2} {\$1} | {date|isodate}\n'
25 > dln = lognull --debug
26 > dln = lognull --debug
26 > nousage = rollback
27 > nousage = rollback
27 > put = export -r 0 -o "\$FOO/%R.diff"
28 > put = export -r 0 -o "\$FOO/%R.diff"
28 > blank = !echo
29 > blank = !echo
29 > self = !echo '\$0'
30 > self = !echo '\$0'
30 > echo = !echo '\$@'
31 > echo = !echo '\$@'
31 > echo1 = !echo '\$1'
32 > echo1 = !echo '\$1'
32 > echo2 = !echo '\$2'
33 > echo2 = !echo '\$2'
33 > echo13 = !echo '\$1' '\$3'
34 > echo13 = !echo '\$1' '\$3'
34 > count = !hg log -r '\$@' --template='.' | wc -c | sed -e 's/ //g'
35 > count = !hg log -r '\$@' --template='.' | wc -c | sed -e 's/ //g'
35 > mcount = !hg log \$@ --template='.' | wc -c | sed -e 's/ //g'
36 > mcount = !hg log \$@ --template='.' | wc -c | sed -e 's/ //g'
36 > rt = root
37 > rt = root
37 > tglog = glog --template "{rev}:{node|short}: '{desc}' {branches}\n"
38 > tglog = glog --template "{rev}:{node|short}: '{desc}' {branches}\n"
38 > idalias = id
39 > idalias = id
39 > idaliaslong = id
40 > idaliaslong = id
40 > idaliasshell = !echo test
41 > idaliasshell = !echo test
41 > parentsshell1 = !echo one
42 > parentsshell1 = !echo one
42 > parentsshell2 = !echo two
43 > parentsshell2 = !echo two
43 > escaped1 = !echo 'test\$\$test'
44 > escaped1 = !echo 'test\$\$test'
44 > escaped2 = !echo "HGFOO is \$\$HGFOO"
45 > escaped2 = !echo "HGFOO is \$\$HGFOO"
45 > escaped3 = !echo "\$1 is \$\$\$1"
46 > escaped3 = !echo "\$1 is \$\$\$1"
46 > escaped4 = !echo '\$\$0' '\$\$@'
47 > escaped4 = !echo '\$\$0' '\$\$@'
47 >
48 >
48 > [defaults]
49 > [defaults]
49 > mylog = -q
50 > mylog = -q
50 > lognull = -q
51 > lognull = -q
51 > log = -v
52 > log = -v
52 > EOF
53 > EOF
53
54
54
55
55 basic
56 basic
56
57
57 $ hg myinit alias
58 $ hg myinit alias
58
59
59
60
60 unknown
61 unknown
61
62
62 $ hg unknown
63 $ hg unknown
63 alias 'unknown' resolves to unknown command 'bargle'
64 alias 'unknown' resolves to unknown command 'bargle'
64 $ hg help unknown
65 $ hg help unknown
65 alias 'unknown' resolves to unknown command 'bargle'
66 alias 'unknown' resolves to unknown command 'bargle'
66
67
67
68
68 ambiguous
69 ambiguous
69
70
70 $ hg ambiguous
71 $ hg ambiguous
71 alias 'ambiguous' resolves to ambiguous command 's'
72 alias 'ambiguous' resolves to ambiguous command 's'
72 $ hg help ambiguous
73 $ hg help ambiguous
73 alias 'ambiguous' resolves to ambiguous command 's'
74 alias 'ambiguous' resolves to ambiguous command 's'
74
75
75
76
76 recursive
77 recursive
77
78
78 $ hg recursive
79 $ hg recursive
79 alias 'recursive' resolves to unknown command 'recursive'
80 alias 'recursive' resolves to unknown command 'recursive'
80 $ hg help recursive
81 $ hg help recursive
81 alias 'recursive' resolves to unknown command 'recursive'
82 alias 'recursive' resolves to unknown command 'recursive'
82
83
83
84
84 no definition
85 no definition
85
86
86 $ hg nodef
87 $ hg nodef
87 no definition for alias 'nodefinition'
88 no definition for alias 'nodefinition'
88 $ hg help nodef
89 $ hg help nodef
89 no definition for alias 'nodefinition'
90 no definition for alias 'nodefinition'
90
91
91
92
92 invalid options
93 invalid options
93
94
94 $ hg no--cwd
95 $ hg no--cwd
95 error in definition for alias 'no--cwd': --cwd may only be given on the command line
96 error in definition for alias 'no--cwd': --cwd may only be given on the command line
96 $ hg help no--cwd
97 $ hg help no--cwd
97 error in definition for alias 'no--cwd': --cwd may only be given on the command line
98 error in definition for alias 'no--cwd': --cwd may only be given on the command line
98 $ hg no-R
99 $ hg no-R
99 error in definition for alias 'no-R': -R may only be given on the command line
100 error in definition for alias 'no-R': -R may only be given on the command line
100 $ hg help no-R
101 $ hg help no-R
101 error in definition for alias 'no-R': -R may only be given on the command line
102 error in definition for alias 'no-R': -R may only be given on the command line
102 $ hg no--repo
103 $ hg no--repo
103 error in definition for alias 'no--repo': --repo may only be given on the command line
104 error in definition for alias 'no--repo': --repo may only be given on the command line
104 $ hg help no--repo
105 $ hg help no--repo
105 error in definition for alias 'no--repo': --repo may only be given on the command line
106 error in definition for alias 'no--repo': --repo may only be given on the command line
106 $ hg no--repository
107 $ hg no--repository
107 error in definition for alias 'no--repository': --repository may only be given on the command line
108 error in definition for alias 'no--repository': --repository may only be given on the command line
108 $ hg help no--repository
109 $ hg help no--repository
109 error in definition for alias 'no--repository': --repository may only be given on the command line
110 error in definition for alias 'no--repository': --repository may only be given on the command line
110
111
112 optional repository
113
114 $ hg optionalrepo
115 init
111 $ cd alias
116 $ cd alias
112
117 $ cat > .hg/hgrc <<EOF
118 > [alias]
119 > myinit = init -q
120 > EOF
121 $ hg optionalrepo
122 init -q
113
123
114 no usage
124 no usage
115
125
116 $ hg nousage
126 $ hg nousage
117 no rollback information available
127 no rollback information available
118
128
119 $ echo foo > foo
129 $ echo foo > foo
120 $ hg commit -Amfoo
130 $ hg commit -Amfoo
121 adding foo
131 adding foo
122
132
123
133
124 with opts
134 with opts
125
135
126 $ hg cleanst
136 $ hg cleanst
127 C foo
137 C foo
128
138
129
139
130 with opts and whitespace
140 with opts and whitespace
131
141
132 $ hg shortlog
142 $ hg shortlog
133 0 e63c23eaa88a | 1970-01-01 00:00 +0000
143 0 e63c23eaa88a | 1970-01-01 00:00 +0000
134
144
135 positional arguments
145 positional arguments
136
146
137 $ hg positional
147 $ hg positional
138 abort: too few arguments for command alias
148 abort: too few arguments for command alias
139 [255]
149 [255]
140 $ hg positional a
150 $ hg positional a
141 abort: too few arguments for command alias
151 abort: too few arguments for command alias
142 [255]
152 [255]
143 $ hg positional 'node|short' rev
153 $ hg positional 'node|short' rev
144 0 e63c23eaa88a | 1970-01-01 00:00 +0000
154 0 e63c23eaa88a | 1970-01-01 00:00 +0000
145
155
146 interaction with defaults
156 interaction with defaults
147
157
148 $ hg mylog
158 $ hg mylog
149 0:e63c23eaa88a
159 0:e63c23eaa88a
150 $ hg lognull
160 $ hg lognull
151 -1:000000000000
161 -1:000000000000
152
162
153
163
154 properly recursive
164 properly recursive
155
165
156 $ hg dln
166 $ hg dln
157 changeset: -1:0000000000000000000000000000000000000000
167 changeset: -1:0000000000000000000000000000000000000000
158 parent: -1:0000000000000000000000000000000000000000
168 parent: -1:0000000000000000000000000000000000000000
159 parent: -1:0000000000000000000000000000000000000000
169 parent: -1:0000000000000000000000000000000000000000
160 manifest: -1:0000000000000000000000000000000000000000
170 manifest: -1:0000000000000000000000000000000000000000
161 user:
171 user:
162 date: Thu Jan 01 00:00:00 1970 +0000
172 date: Thu Jan 01 00:00:00 1970 +0000
163 extra: branch=default
173 extra: branch=default
164
174
165
175
166
176
167 path expanding
177 path expanding
168
178
169 $ FOO=`pwd` hg put
179 $ FOO=`pwd` hg put
170 $ cat 0.diff
180 $ cat 0.diff
171 # HG changeset patch
181 # HG changeset patch
172 # User test
182 # User test
173 # Date 0 0
183 # Date 0 0
174 # Node ID e63c23eaa88ae77967edcf4ea194d31167c478b0
184 # Node ID e63c23eaa88ae77967edcf4ea194d31167c478b0
175 # Parent 0000000000000000000000000000000000000000
185 # Parent 0000000000000000000000000000000000000000
176 foo
186 foo
177
187
178 diff -r 000000000000 -r e63c23eaa88a foo
188 diff -r 000000000000 -r e63c23eaa88a foo
179 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
189 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
180 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
190 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
181 @@ -0,0 +1,1 @@
191 @@ -0,0 +1,1 @@
182 +foo
192 +foo
183
193
184
194
185 simple shell aliases
195 simple shell aliases
186
196
187 $ hg blank
197 $ hg blank
188
198
189 $ hg blank foo
199 $ hg blank foo
190
200
191 $ hg self
201 $ hg self
192 self
202 self
193 $ hg echo
203 $ hg echo
194
204
195 $ hg echo foo
205 $ hg echo foo
196 foo
206 foo
197 $ hg echo 'test $2' foo
207 $ hg echo 'test $2' foo
198 test $2 foo
208 test $2 foo
199 $ hg echo1 foo bar baz
209 $ hg echo1 foo bar baz
200 foo
210 foo
201 $ hg echo2 foo bar baz
211 $ hg echo2 foo bar baz
202 bar
212 bar
203 $ hg echo13 foo bar baz test
213 $ hg echo13 foo bar baz test
204 foo baz
214 foo baz
205 $ hg echo2 foo
215 $ hg echo2 foo
206
216
207 $ echo bar > bar
217 $ echo bar > bar
208 $ hg commit -qA -m bar
218 $ hg commit -qA -m bar
209 $ hg count .
219 $ hg count .
210 1
220 1
211 $ hg count 'branch(default)'
221 $ hg count 'branch(default)'
212 2
222 2
213 $ hg mcount -r '"branch(default)"'
223 $ hg mcount -r '"branch(default)"'
214 2
224 2
215
225
216 $ hg tglog
226 $ hg tglog
217 @ 1:7e7f92de180e: 'bar'
227 @ 1:7e7f92de180e: 'bar'
218 |
228 |
219 o 0:e63c23eaa88a: 'foo'
229 o 0:e63c23eaa88a: 'foo'
220
230
221
231
222
232
223 shadowing
233 shadowing
224
234
225 $ hg i
235 $ hg i
226 hg: command 'i' is ambiguous:
236 hg: command 'i' is ambiguous:
227 idalias idaliaslong idaliasshell identify import incoming init
237 idalias idaliaslong idaliasshell identify import incoming init
228 [255]
238 [255]
229 $ hg id
239 $ hg id
230 7e7f92de180e tip
240 7e7f92de180e tip
231 $ hg ida
241 $ hg ida
232 hg: command 'ida' is ambiguous:
242 hg: command 'ida' is ambiguous:
233 idalias idaliaslong idaliasshell
243 idalias idaliaslong idaliasshell
234 [255]
244 [255]
235 $ hg idalias
245 $ hg idalias
236 7e7f92de180e tip
246 7e7f92de180e tip
237 $ hg idaliasl
247 $ hg idaliasl
238 7e7f92de180e tip
248 7e7f92de180e tip
239 $ hg idaliass
249 $ hg idaliass
240 test
250 test
241 $ hg parentsshell
251 $ hg parentsshell
242 hg: command 'parentsshell' is ambiguous:
252 hg: command 'parentsshell' is ambiguous:
243 parentsshell1 parentsshell2
253 parentsshell1 parentsshell2
244 [255]
254 [255]
245 $ hg parentsshell1
255 $ hg parentsshell1
246 one
256 one
247 $ hg parentsshell2
257 $ hg parentsshell2
248 two
258 two
249
259
250
260
251 shell aliases with global options
261 shell aliases with global options
252
262
253 $ hg init sub
263 $ hg init sub
254 $ cd sub
264 $ cd sub
255 $ hg count 'branch(default)'
265 $ hg count 'branch(default)'
256 0
266 0
257 $ hg -v count 'branch(default)'
267 $ hg -v count 'branch(default)'
258 0
268 0
259 $ hg -R .. count 'branch(default)'
269 $ hg -R .. count 'branch(default)'
260 0
270 0
261 $ hg --cwd .. count 'branch(default)'
271 $ hg --cwd .. count 'branch(default)'
262 2
272 2
263 $ hg echo --cwd ..
273 $ hg echo --cwd ..
264
274
265
275
266
276
267 repo specific shell aliases
277 repo specific shell aliases
268
278
269 $ cat >> .hg/hgrc <<EOF
279 $ cat >> .hg/hgrc <<EOF
270 > [alias]
280 > [alias]
271 > subalias = !echo sub \$@
281 > subalias = !echo sub \$@
272 > EOF
282 > EOF
273 $ cat >> ../.hg/hgrc <<EOF
283 $ cat >> ../.hg/hgrc <<EOF
274 > [alias]
284 > [alias]
275 > mainalias = !echo main \$@
285 > mainalias = !echo main \$@
276 > EOF
286 > EOF
277
287
278
288
279 shell alias defined in current repo
289 shell alias defined in current repo
280
290
281 $ hg subalias
291 $ hg subalias
282 sub
292 sub
283 $ hg --cwd .. subalias > /dev/null
293 $ hg --cwd .. subalias > /dev/null
284 hg: unknown command 'subalias'
294 hg: unknown command 'subalias'
285 [255]
295 [255]
286 $ hg -R .. subalias > /dev/null
296 $ hg -R .. subalias > /dev/null
287 hg: unknown command 'subalias'
297 hg: unknown command 'subalias'
288 [255]
298 [255]
289
299
290
300
291 shell alias defined in other repo
301 shell alias defined in other repo
292
302
293 $ hg mainalias > /dev/null
303 $ hg mainalias > /dev/null
294 hg: unknown command 'mainalias'
304 hg: unknown command 'mainalias'
295 [255]
305 [255]
296 $ hg -R .. mainalias
306 $ hg -R .. mainalias
297 main
307 main
298 $ hg --cwd .. mainalias
308 $ hg --cwd .. mainalias
299 main
309 main
300
310
301
311
302 shell aliases with escaped $ chars
312 shell aliases with escaped $ chars
303
313
304 $ hg escaped1
314 $ hg escaped1
305 test$test
315 test$test
306 $ hg escaped2
316 $ hg escaped2
307 HGFOO is BAR
317 HGFOO is BAR
308 $ hg escaped3 HGFOO
318 $ hg escaped3 HGFOO
309 HGFOO is BAR
319 HGFOO is BAR
310 $ hg escaped4 test
320 $ hg escaped4 test
311 $0 $@
321 $0 $@
312
322
313
323
314 invalid arguments
324 invalid arguments
315
325
316 $ hg rt foo
326 $ hg rt foo
317 hg rt: invalid arguments
327 hg rt: invalid arguments
318 hg rt
328 hg rt
319
329
320 alias for: hg root
330 alias for: hg root
321
331
322 use "hg help rt" to show the full help text
332 use "hg help rt" to show the full help text
323 [255]
333 [255]
324
334
325 invalid global arguments for normal commands, aliases, and shell aliases
335 invalid global arguments for normal commands, aliases, and shell aliases
326
336
327 $ hg --invalid root
337 $ hg --invalid root
328 hg: option --invalid not recognized
338 hg: option --invalid not recognized
329 Mercurial Distributed SCM
339 Mercurial Distributed SCM
330
340
331 basic commands:
341 basic commands:
332
342
333 add add the specified files on the next commit
343 add add the specified files on the next commit
334 annotate show changeset information by line for each file
344 annotate show changeset information by line for each file
335 clone make a copy of an existing repository
345 clone make a copy of an existing repository
336 commit commit the specified files or all outstanding changes
346 commit commit the specified files or all outstanding changes
337 diff diff repository (or selected files)
347 diff diff repository (or selected files)
338 export dump the header and diffs for one or more changesets
348 export dump the header and diffs for one or more changesets
339 forget forget the specified files on the next commit
349 forget forget the specified files on the next commit
340 init create a new repository in the given directory
350 init create a new repository in the given directory
341 log show revision history of entire repository or files
351 log show revision history of entire repository or files
342 merge merge working directory with another revision
352 merge merge working directory with another revision
343 phase set or show the current phase name
353 phase set or show the current phase name
344 pull pull changes from the specified source
354 pull pull changes from the specified source
345 push push changes to the specified destination
355 push push changes to the specified destination
346 remove remove the specified files on the next commit
356 remove remove the specified files on the next commit
347 serve start stand-alone webserver
357 serve start stand-alone webserver
348 status show changed files in the working directory
358 status show changed files in the working directory
349 summary summarize working directory state
359 summary summarize working directory state
350 update update working directory (or switch revisions)
360 update update working directory (or switch revisions)
351
361
352 use "hg help" for the full list of commands or "hg -v" for details
362 use "hg help" for the full list of commands or "hg -v" for details
353 [255]
363 [255]
354 $ hg --invalid mylog
364 $ hg --invalid mylog
355 hg: option --invalid not recognized
365 hg: option --invalid not recognized
356 Mercurial Distributed SCM
366 Mercurial Distributed SCM
357
367
358 basic commands:
368 basic commands:
359
369
360 add add the specified files on the next commit
370 add add the specified files on the next commit
361 annotate show changeset information by line for each file
371 annotate show changeset information by line for each file
362 clone make a copy of an existing repository
372 clone make a copy of an existing repository
363 commit commit the specified files or all outstanding changes
373 commit commit the specified files or all outstanding changes
364 diff diff repository (or selected files)
374 diff diff repository (or selected files)
365 export dump the header and diffs for one or more changesets
375 export dump the header and diffs for one or more changesets
366 forget forget the specified files on the next commit
376 forget forget the specified files on the next commit
367 init create a new repository in the given directory
377 init create a new repository in the given directory
368 log show revision history of entire repository or files
378 log show revision history of entire repository or files
369 merge merge working directory with another revision
379 merge merge working directory with another revision
370 phase set or show the current phase name
380 phase set or show the current phase name
371 pull pull changes from the specified source
381 pull pull changes from the specified source
372 push push changes to the specified destination
382 push push changes to the specified destination
373 remove remove the specified files on the next commit
383 remove remove the specified files on the next commit
374 serve start stand-alone webserver
384 serve start stand-alone webserver
375 status show changed files in the working directory
385 status show changed files in the working directory
376 summary summarize working directory state
386 summary summarize working directory state
377 update update working directory (or switch revisions)
387 update update working directory (or switch revisions)
378
388
379 use "hg help" for the full list of commands or "hg -v" for details
389 use "hg help" for the full list of commands or "hg -v" for details
380 [255]
390 [255]
381 $ hg --invalid blank
391 $ hg --invalid blank
382 hg: option --invalid not recognized
392 hg: option --invalid not recognized
383 Mercurial Distributed SCM
393 Mercurial Distributed SCM
384
394
385 basic commands:
395 basic commands:
386
396
387 add add the specified files on the next commit
397 add add the specified files on the next commit
388 annotate show changeset information by line for each file
398 annotate show changeset information by line for each file
389 clone make a copy of an existing repository
399 clone make a copy of an existing repository
390 commit commit the specified files or all outstanding changes
400 commit commit the specified files or all outstanding changes
391 diff diff repository (or selected files)
401 diff diff repository (or selected files)
392 export dump the header and diffs for one or more changesets
402 export dump the header and diffs for one or more changesets
393 forget forget the specified files on the next commit
403 forget forget the specified files on the next commit
394 init create a new repository in the given directory
404 init create a new repository in the given directory
395 log show revision history of entire repository or files
405 log show revision history of entire repository or files
396 merge merge working directory with another revision
406 merge merge working directory with another revision
397 phase set or show the current phase name
407 phase set or show the current phase name
398 pull pull changes from the specified source
408 pull pull changes from the specified source
399 push push changes to the specified destination
409 push push changes to the specified destination
400 remove remove the specified files on the next commit
410 remove remove the specified files on the next commit
401 serve start stand-alone webserver
411 serve start stand-alone webserver
402 status show changed files in the working directory
412 status show changed files in the working directory
403 summary summarize working directory state
413 summary summarize working directory state
404 update update working directory (or switch revisions)
414 update update working directory (or switch revisions)
405
415
406 use "hg help" for the full list of commands or "hg -v" for details
416 use "hg help" for the full list of commands or "hg -v" for details
407 [255]
417 [255]
408
418
409 This should show id:
419 This should show id:
410
420
411 $ hg --config alias.log='id' log
421 $ hg --config alias.log='id' log
412 000000000000 tip
422 000000000000 tip
413
423
414 This shouldn't:
424 This shouldn't:
415
425
416 $ hg --config alias.log='id' history
426 $ hg --config alias.log='id' history
General Comments 0
You need to be logged in to leave comments. Login now