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