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