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