changeset 4549 | 0c61124ad877 |
parent 4548 | c9fcebbfc422 |
child 4561 | a73d80d6385a |
4548:c9fcebbfc422 | 4549:0c61124ad877 |
---|---|
6 # of the GNU General Public License, incorporated herein by reference. |
6 # of the GNU General Public License, incorporated herein by reference. |
7 |
7 |
8 import demandimport; demandimport.enable() |
8 import demandimport; demandimport.enable() |
9 from node import * |
9 from node import * |
10 from i18n import _ |
10 from i18n import _ |
11 import bisect, os, re, sys, signal, urllib, pdb, shlex, stat |
11 import bisect, os, re, sys, urllib, shlex, stat |
12 import fancyopts, ui, hg, util, lock, revlog, bundlerepo, extensions |
12 import ui, hg, util, revlog, bundlerepo, extensions |
13 import difflib, patch, time, help, mdiff, tempfile |
13 import difflib, patch, time, help, mdiff, tempfile |
14 import traceback, errno, version, atexit, socket |
14 import errno, version, socket |
15 import archival, changegroup, cmdutil, hgweb.server, sshserver |
15 import archival, changegroup, cmdutil, hgweb.server, sshserver |
16 |
|
17 class UnknownCommand(Exception): |
|
18 """Exception raised if command is not in the command table.""" |
|
19 class AmbiguousCommand(Exception): |
|
20 """Exception raised if command shortcut matches more than one command.""" |
|
21 |
|
22 def bail_if_changed(repo): |
|
23 modified, added, removed, deleted = repo.status()[:4] |
|
24 if modified or added or removed or deleted: |
|
25 raise util.Abort(_("outstanding uncommitted changes")) |
|
26 |
|
27 def logmessage(opts): |
|
28 """ get the log message according to -m and -l option """ |
|
29 message = opts['message'] |
|
30 logfile = opts['logfile'] |
|
31 |
|
32 if message and logfile: |
|
33 raise util.Abort(_('options --message and --logfile are mutually ' |
|
34 'exclusive')) |
|
35 if not message and logfile: |
|
36 try: |
|
37 if logfile == '-': |
|
38 message = sys.stdin.read() |
|
39 else: |
|
40 message = open(logfile).read() |
|
41 except IOError, inst: |
|
42 raise util.Abort(_("can't read commit message '%s': %s") % |
|
43 (logfile, inst.strerror)) |
|
44 return message |
|
45 |
|
46 def setremoteconfig(ui, opts): |
|
47 "copy remote options to ui tree" |
|
48 if opts.get('ssh'): |
|
49 ui.setconfig("ui", "ssh", opts['ssh']) |
|
50 if opts.get('remotecmd'): |
|
51 ui.setconfig("ui", "remotecmd", opts['remotecmd']) |
|
52 |
16 |
53 # Commands start here, listed alphabetically |
17 # Commands start here, listed alphabetically |
54 |
18 |
55 def add(ui, repo, *pats, **opts): |
19 def add(ui, repo, *pats, **opts): |
56 """add the specified files on the next commit |
20 """add the specified files on the next commit |
203 raise util.Abort(_("please specify just one revision")) |
167 raise util.Abort(_("please specify just one revision")) |
204 |
168 |
205 if not rev: |
169 if not rev: |
206 rev = node |
170 rev = node |
207 |
171 |
208 bail_if_changed(repo) |
172 cmdutil.bail_if_changed(repo) |
209 op1, op2 = repo.dirstate.parents() |
173 op1, op2 = repo.dirstate.parents() |
210 if op2 != nullid: |
174 if op2 != nullid: |
211 raise util.Abort(_('outstanding uncommitted merge')) |
175 raise util.Abort(_('outstanding uncommitted merge')) |
212 node = repo.lookup(rev) |
176 node = repo.lookup(rev) |
213 p1, p2 = repo.changelog.parents(node) |
177 p1, p2 = repo.changelog.parents(node) |
333 for p in parents: |
297 for p in parents: |
334 if p not in seen: |
298 if p not in seen: |
335 seen[p] = 1 |
299 seen[p] = 1 |
336 visit.append(p) |
300 visit.append(p) |
337 else: |
301 else: |
338 setremoteconfig(ui, opts) |
302 cmdutil.setremoteconfig(ui, opts) |
339 dest, revs = cmdutil.parseurl( |
303 dest, revs = cmdutil.parseurl( |
340 ui.expandpath(dest or 'default-push', dest or 'default'), revs) |
304 ui.expandpath(dest or 'default-push', dest or 'default'), revs) |
341 other = hg.repository(ui, dest) |
305 other = hg.repository(ui, dest) |
342 o = repo.findoutgoing(other, force=opts['force']) |
306 o = repo.findoutgoing(other, force=opts['force']) |
343 |
307 |
405 It is possible to specify an ssh:// URL as the destination, but no |
369 It is possible to specify an ssh:// URL as the destination, but no |
406 .hg/hgrc and working directory will be created on the remote side. |
370 .hg/hgrc and working directory will be created on the remote side. |
407 Look at the help text for the pull command for important details |
371 Look at the help text for the pull command for important details |
408 about ssh:// URLs. |
372 about ssh:// URLs. |
409 """ |
373 """ |
410 setremoteconfig(ui, opts) |
374 cmdutil.setremoteconfig(ui, opts) |
411 hg.clone(ui, source, dest, |
375 hg.clone(ui, source, dest, |
412 pull=opts['pull'], |
376 pull=opts['pull'], |
413 stream=opts['uncompressed'], |
377 stream=opts['uncompressed'], |
414 rev=opts['rev'], |
378 rev=opts['rev'], |
415 update=not opts['noupdate']) |
379 update=not opts['noupdate']) |
423 will be committed. |
387 will be committed. |
424 |
388 |
425 If no commit message is specified, the editor configured in your hgrc |
389 If no commit message is specified, the editor configured in your hgrc |
426 or in the EDITOR environment variable is started to enter a message. |
390 or in the EDITOR environment variable is started to enter a message. |
427 """ |
391 """ |
428 message = logmessage(opts) |
392 message = cmdutil.logmessage(opts) |
429 |
393 |
430 if opts['addremove']: |
394 if opts['addremove']: |
431 cmdutil.addremove(repo, pats, opts) |
395 cmdutil.addremove(repo, pats, opts) |
432 fns, match, anypats = cmdutil.matchpats(repo, pats, opts) |
396 fns, match, anypats = cmdutil.matchpats(repo, pats, opts) |
433 if pats: |
397 if pats: |
683 |
647 |
684 if opts['options']: |
648 if opts['options']: |
685 options = [] |
649 options = [] |
686 otables = [globalopts] |
650 otables = [globalopts] |
687 if cmd: |
651 if cmd: |
688 aliases, entry = findcmd(ui, cmd) |
652 aliases, entry = cmdutil.findcmd(ui, cmd) |
689 otables.append(entry[1]) |
653 otables.append(entry[1]) |
690 for t in otables: |
654 for t in otables: |
691 for o in t: |
655 for o in t: |
692 if o[0]: |
656 if o[0]: |
693 options.append('-%s' % o[0]) |
657 options.append('-%s' % o[0]) |
694 options.append('--%s' % o[1]) |
658 options.append('--%s' % o[1]) |
695 ui.write("%s\n" % "\n".join(options)) |
659 ui.write("%s\n" % "\n".join(options)) |
696 return |
660 return |
697 |
661 |
698 clist = findpossible(ui, cmd).keys() |
662 clist = cmdutil.findpossible(ui, cmd).keys() |
699 clist.sort() |
663 clist.sort() |
700 ui.write("%s\n" % "\n".join(clist)) |
664 ui.write("%s\n" % "\n".join(clist)) |
701 |
665 |
702 def debugrebuildstate(ui, repo, rev=""): |
666 def debugrebuildstate(ui, repo, rev=""): |
703 """rebuild the dirstate as it would look like for the given revision""" |
667 """rebuild the dirstate as it would look like for the given revision""" |
1293 |
1257 |
1294 def helpcmd(name): |
1258 def helpcmd(name): |
1295 if with_version: |
1259 if with_version: |
1296 version_(ui) |
1260 version_(ui) |
1297 ui.write('\n') |
1261 ui.write('\n') |
1298 aliases, i = findcmd(ui, name) |
1262 aliases, i = cmdutil.findcmd(ui, name) |
1299 # synopsis |
1263 # synopsis |
1300 ui.write("%s\n\n" % i[2]) |
1264 ui.write("%s\n\n" % i[2]) |
1301 |
1265 |
1302 # description |
1266 # description |
1303 doc = i[0].__doc__ |
1267 doc = i[0].__doc__ |
1355 l = i.split('|') |
1319 l = i.split('|') |
1356 if name in l: |
1320 if name in l: |
1357 v = i |
1321 v = i |
1358 header = l[-1] |
1322 header = l[-1] |
1359 if not v: |
1323 if not v: |
1360 raise UnknownCommand(name) |
1324 raise cmdutil.UnknownCommand(name) |
1361 |
1325 |
1362 # description |
1326 # description |
1363 doc = help.helptable[v] |
1327 doc = help.helptable[v] |
1364 if not doc: |
1328 if not doc: |
1365 doc = _("(No help text available)") |
1329 doc = _("(No help text available)") |
1371 |
1335 |
1372 def helpext(name): |
1336 def helpext(name): |
1373 try: |
1337 try: |
1374 mod = extensions.find(name) |
1338 mod = extensions.find(name) |
1375 except KeyError: |
1339 except KeyError: |
1376 raise UnknownCommand(name) |
1340 raise cmdutil.UnknownCommand(name) |
1377 |
1341 |
1378 doc = (mod.__doc__ or _('No help text available')).splitlines(0) |
1342 doc = (mod.__doc__ or _('No help text available')).splitlines(0) |
1379 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0])) |
1343 ui.write(_('%s extension - %s\n') % (name.split('.')[-1], doc[0])) |
1380 for d in doc[1:]: |
1344 for d in doc[1:]: |
1381 ui.write(d, '\n') |
1345 ui.write(d, '\n') |
1397 for f in (helpcmd, helptopic, helpext): |
1361 for f in (helpcmd, helptopic, helpext): |
1398 try: |
1362 try: |
1399 f(name) |
1363 f(name) |
1400 i = None |
1364 i = None |
1401 break |
1365 break |
1402 except UnknownCommand, inst: |
1366 except cmdutil.UnknownCommand, inst: |
1403 i = inst |
1367 i = inst |
1404 if i: |
1368 if i: |
1405 raise i |
1369 raise i |
1406 |
1370 |
1407 else: |
1371 else: |
1504 To read a patch from standard input, use patch name "-". |
1468 To read a patch from standard input, use patch name "-". |
1505 """ |
1469 """ |
1506 patches = (patch1,) + patches |
1470 patches = (patch1,) + patches |
1507 |
1471 |
1508 if opts.get('exact') or not opts['force']: |
1472 if opts.get('exact') or not opts['force']: |
1509 bail_if_changed(repo) |
1473 cmdutil.bail_if_changed(repo) |
1510 |
1474 |
1511 d = opts["base"] |
1475 d = opts["base"] |
1512 strip = opts["strip"] |
1476 strip = opts["strip"] |
1513 |
1477 |
1514 wlock = repo.wlock() |
1478 wlock = repo.wlock() |
1526 |
1490 |
1527 if tmpname is None: |
1491 if tmpname is None: |
1528 raise util.Abort(_('no diffs found')) |
1492 raise util.Abort(_('no diffs found')) |
1529 |
1493 |
1530 try: |
1494 try: |
1531 cmdline_message = logmessage(opts) |
1495 cmdline_message = cmdutil.logmessage(opts) |
1532 if cmdline_message: |
1496 if cmdline_message: |
1533 # pickup the cmdline msg |
1497 # pickup the cmdline msg |
1534 message = cmdline_message |
1498 message = cmdline_message |
1535 elif message: |
1499 elif message: |
1536 # pickup the patch msg |
1500 # pickup the patch msg |
1585 twice if the incoming is followed by a pull. |
1549 twice if the incoming is followed by a pull. |
1586 |
1550 |
1587 See pull for valid source format details. |
1551 See pull for valid source format details. |
1588 """ |
1552 """ |
1589 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev']) |
1553 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev']) |
1590 setremoteconfig(ui, opts) |
1554 cmdutil.setremoteconfig(ui, opts) |
1591 |
1555 |
1592 other = hg.repository(ui, source) |
1556 other = hg.repository(ui, source) |
1593 ui.status(_('comparing with %s\n') % source) |
1557 ui.status(_('comparing with %s\n') % source) |
1594 if revs: |
1558 if revs: |
1595 if 'lookup' in other.capabilities: |
1559 if 'lookup' in other.capabilities: |
1651 |
1615 |
1652 It is possible to specify an ssh:// URL as the destination. |
1616 It is possible to specify an ssh:// URL as the destination. |
1653 Look at the help text for the pull command for important details |
1617 Look at the help text for the pull command for important details |
1654 about ssh:// URLs. |
1618 about ssh:// URLs. |
1655 """ |
1619 """ |
1656 setremoteconfig(ui, opts) |
1620 cmdutil.setremoteconfig(ui, opts) |
1657 hg.repository(ui, dest, create=1) |
1621 hg.repository(ui, dest, create=1) |
1658 |
1622 |
1659 def locate(ui, repo, *pats, **opts): |
1623 def locate(ui, repo, *pats, **opts): |
1660 """locate files matching specific patterns |
1624 """locate files matching specific patterns |
1661 |
1625 |
1888 |
1852 |
1889 See pull for valid destination format details. |
1853 See pull for valid destination format details. |
1890 """ |
1854 """ |
1891 dest, revs = cmdutil.parseurl( |
1855 dest, revs = cmdutil.parseurl( |
1892 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev']) |
1856 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev']) |
1893 setremoteconfig(ui, opts) |
1857 cmdutil.setremoteconfig(ui, opts) |
1894 if revs: |
1858 if revs: |
1895 revs = [repo.lookup(rev) for rev in revs] |
1859 revs = [repo.lookup(rev) for rev in revs] |
1896 |
1860 |
1897 other = hg.repository(ui, dest) |
1861 other = hg.repository(ui, dest) |
1898 ui.status(_('comparing with %s\n') % dest) |
1862 ui.status(_('comparing with %s\n') % dest) |
2003 Compression yes |
1967 Compression yes |
2004 Alternatively specify "ssh -C" as your ssh command in your hgrc or |
1968 Alternatively specify "ssh -C" as your ssh command in your hgrc or |
2005 with the --ssh command line option. |
1969 with the --ssh command line option. |
2006 """ |
1970 """ |
2007 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev']) |
1971 source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev']) |
2008 setremoteconfig(ui, opts) |
1972 cmdutil.setremoteconfig(ui, opts) |
2009 |
1973 |
2010 other = hg.repository(ui, source) |
1974 other = hg.repository(ui, source) |
2011 ui.status(_('pulling from %s\n') % (source)) |
1975 ui.status(_('pulling from %s\n') % (source)) |
2012 if revs: |
1976 if revs: |
2013 if 'lookup' in other.capabilities: |
1977 if 'lookup' in other.capabilities: |
2049 Pushing to http:// and https:// URLs is only possible, if this |
2013 Pushing to http:// and https:// URLs is only possible, if this |
2050 feature is explicitly enabled on the remote Mercurial server. |
2014 feature is explicitly enabled on the remote Mercurial server. |
2051 """ |
2015 """ |
2052 dest, revs = cmdutil.parseurl( |
2016 dest, revs = cmdutil.parseurl( |
2053 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev']) |
2017 ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev']) |
2054 setremoteconfig(ui, opts) |
2018 cmdutil.setremoteconfig(ui, opts) |
2055 |
2019 |
2056 other = hg.repository(ui, dest) |
2020 other = hg.repository(ui, dest) |
2057 ui.status('pushing to %s\n' % (dest)) |
2021 ui.status('pushing to %s\n' % (dest)) |
2058 if revs: |
2022 if revs: |
2059 revs = [repo.lookup(rev) for rev in revs] |
2023 revs = [repo.lookup(rev) for rev in revs] |
2073 release, please use debugsetparents and commit instead. |
2037 release, please use debugsetparents and commit instead. |
2074 """ |
2038 """ |
2075 |
2039 |
2076 ui.warn(_("(the rawcommit command is deprecated)\n")) |
2040 ui.warn(_("(the rawcommit command is deprecated)\n")) |
2077 |
2041 |
2078 message = logmessage(opts) |
2042 message = cmdutil.logmessage(opts) |
2079 |
2043 |
2080 files, match, anypats = cmdutil.matchpats(repo, pats, opts) |
2044 files, match, anypats = cmdutil.matchpats(repo, pats, opts) |
2081 if opts['files']: |
2045 if opts['files']: |
2082 files += open(opts['files']).read().splitlines() |
2046 files += open(opts['files']).read().splitlines() |
2083 |
2047 |
3037 try: |
3001 try: |
3038 u = ui.ui(traceback='--traceback' in sys.argv[1:]) |
3002 u = ui.ui(traceback='--traceback' in sys.argv[1:]) |
3039 except util.Abort, inst: |
3003 except util.Abort, inst: |
3040 sys.stderr.write(_("abort: %s\n") % inst) |
3004 sys.stderr.write(_("abort: %s\n") % inst) |
3041 return -1 |
3005 return -1 |
3042 sys.exit(runcatch(u, sys.argv[1:])) |
3006 sys.exit(cmdutil.runcatch(u, sys.argv[1:])) |
3043 |
3007 |
3044 def runcatch(u, args): |
|
3045 def catchterm(*args): |
|
3046 raise util.SignalInterrupt |
|
3047 |
|
3048 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM': |
|
3049 num = getattr(signal, name, None) |
|
3050 if num: signal.signal(num, catchterm) |
|
3051 |
|
3052 try: |
|
3053 return dispatch(u, args) |
|
3054 except hg.RepoError, inst: |
|
3055 u.warn(_("abort: %s!\n") % inst) |
|
3056 except lock.LockHeld, inst: |
|
3057 if inst.errno == errno.ETIMEDOUT: |
|
3058 reason = _('timed out waiting for lock held by %s') % inst.locker |
|
3059 else: |
|
3060 reason = _('lock held by %s') % inst.locker |
|
3061 u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason)) |
|
3062 except lock.LockUnavailable, inst: |
|
3063 u.warn(_("abort: could not lock %s: %s\n") % |
|
3064 (inst.desc or inst.filename, inst.strerror)) |
|
3065 except revlog.RevlogError, inst: |
|
3066 u.warn(_("abort: %s!\n") % inst) |
|
3067 except util.SignalInterrupt: |
|
3068 u.warn(_("killed!\n")) |
|
3069 except KeyboardInterrupt: |
|
3070 try: |
|
3071 u.warn(_("interrupted!\n")) |
|
3072 except IOError, inst: |
|
3073 if inst.errno == errno.EPIPE: |
|
3074 if u.debugflag: |
|
3075 u.warn(_("\nbroken pipe\n")) |
|
3076 else: |
|
3077 raise |
|
3078 except socket.error, inst: |
|
3079 u.warn(_("abort: %s\n") % inst[1]) |
|
3080 except IOError, inst: |
|
3081 if hasattr(inst, "code"): |
|
3082 u.warn(_("abort: %s\n") % inst) |
|
3083 elif hasattr(inst, "reason"): |
|
3084 try: # usually it is in the form (errno, strerror) |
|
3085 reason = inst.reason.args[1] |
|
3086 except: # it might be anything, for example a string |
|
3087 reason = inst.reason |
|
3088 u.warn(_("abort: error: %s\n") % reason) |
|
3089 elif hasattr(inst, "args") and inst[0] == errno.EPIPE: |
|
3090 if u.debugflag: |
|
3091 u.warn(_("broken pipe\n")) |
|
3092 elif getattr(inst, "strerror", None): |
|
3093 if getattr(inst, "filename", None): |
|
3094 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename)) |
|
3095 else: |
|
3096 u.warn(_("abort: %s\n") % inst.strerror) |
|
3097 else: |
|
3098 raise |
|
3099 except OSError, inst: |
|
3100 if getattr(inst, "filename", None): |
|
3101 u.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename)) |
|
3102 else: |
|
3103 u.warn(_("abort: %s\n") % inst.strerror) |
|
3104 except util.UnexpectedOutput, inst: |
|
3105 u.warn(_("abort: %s") % inst[0]) |
|
3106 if not isinstance(inst[1], basestring): |
|
3107 u.warn(" %r\n" % (inst[1],)) |
|
3108 elif not inst[1]: |
|
3109 u.warn(_(" empty string\n")) |
|
3110 else: |
|
3111 u.warn("\n%r\n" % util.ellipsis(inst[1])) |
|
3112 except util.Abort, inst: |
|
3113 u.warn(_("abort: %s\n") % inst) |
|
3114 except TypeError, inst: |
|
3115 # was this an argument error? |
|
3116 tb = traceback.extract_tb(sys.exc_info()[2]) |
|
3117 if len(tb) > 2: # no |
|
3118 raise |
|
3119 u.debug(inst, "\n") |
|
3120 u.warn(_("%s: invalid arguments\n") % cmd) |
|
3121 help_(u, cmd) |
|
3122 except SystemExit, inst: |
|
3123 # Commands shouldn't sys.exit directly, but give a return code. |
|
3124 # Just in case catch this and and pass exit code to caller. |
|
3125 return inst.code |
|
3126 except: |
|
3127 u.warn(_("** unknown exception encountered, details follow\n")) |
|
3128 u.warn(_("** report bug details to " |
|
3129 "http://www.selenic.com/mercurial/bts\n")) |
|
3130 u.warn(_("** or mercurial@selenic.com\n")) |
|
3131 u.warn(_("** Mercurial Distributed SCM (version %s)\n") |
|
3132 % version.get_version()) |
|
3133 raise |
|
3134 |
|
3135 return -1 |
|
3136 |
|
3137 def findpossible(ui, cmd): |
|
3138 """ |
|
3139 Return cmd -> (aliases, command table entry) |
|
3140 for each matching command. |
|
3141 Return debug commands (or their aliases) only if no normal command matches. |
|
3142 """ |
|
3143 choice = {} |
|
3144 debugchoice = {} |
|
3145 for e in table.keys(): |
|
3146 aliases = e.lstrip("^").split("|") |
|
3147 found = None |
|
3148 if cmd in aliases: |
|
3149 found = cmd |
|
3150 elif not ui.config("ui", "strict"): |
|
3151 for a in aliases: |
|
3152 if a.startswith(cmd): |
|
3153 found = a |
|
3154 break |
|
3155 if found is not None: |
|
3156 if aliases[0].startswith("debug") or found.startswith("debug"): |
|
3157 debugchoice[found] = (aliases, table[e]) |
|
3158 else: |
|
3159 choice[found] = (aliases, table[e]) |
|
3160 |
|
3161 if not choice and debugchoice: |
|
3162 choice = debugchoice |
|
3163 |
|
3164 return choice |
|
3165 |
|
3166 def findcmd(ui, cmd): |
|
3167 """Return (aliases, command table entry) for command string.""" |
|
3168 choice = findpossible(ui, cmd) |
|
3169 |
|
3170 if choice.has_key(cmd): |
|
3171 return choice[cmd] |
|
3172 |
|
3173 if len(choice) > 1: |
|
3174 clist = choice.keys() |
|
3175 clist.sort() |
|
3176 raise AmbiguousCommand(cmd, clist) |
|
3177 |
|
3178 if choice: |
|
3179 return choice.values()[0] |
|
3180 |
|
3181 raise UnknownCommand(cmd) |
|
3182 |
|
3183 class ParseError(Exception): |
|
3184 """Exception raised on errors in parsing the command line.""" |
|
3185 |
|
3186 def parse(ui, args): |
|
3187 options = {} |
|
3188 cmdoptions = {} |
|
3189 |
|
3190 try: |
|
3191 args = fancyopts.fancyopts(args, globalopts, options) |
|
3192 except fancyopts.getopt.GetoptError, inst: |
|
3193 raise ParseError(None, inst) |
|
3194 |
|
3195 if args: |
|
3196 cmd, args = args[0], args[1:] |
|
3197 aliases, i = findcmd(ui, cmd) |
|
3198 cmd = aliases[0] |
|
3199 defaults = ui.config("defaults", cmd) |
|
3200 if defaults: |
|
3201 args = shlex.split(defaults) + args |
|
3202 c = list(i[1]) |
|
3203 else: |
|
3204 cmd = None |
|
3205 c = [] |
|
3206 |
|
3207 # combine global options into local |
|
3208 for o in globalopts: |
|
3209 c.append((o[0], o[1], options[o[1]], o[3])) |
|
3210 |
|
3211 try: |
|
3212 args = fancyopts.fancyopts(args, c, cmdoptions) |
|
3213 except fancyopts.getopt.GetoptError, inst: |
|
3214 raise ParseError(cmd, inst) |
|
3215 |
|
3216 # separate global options back out |
|
3217 for o in globalopts: |
|
3218 n = o[1] |
|
3219 options[n] = cmdoptions[n] |
|
3220 del cmdoptions[n] |
|
3221 |
|
3222 return (cmd, cmd and i[0] or None, args, options, cmdoptions) |
|
3223 |
|
3224 def parseconfig(config): |
|
3225 """parse the --config options from the command line""" |
|
3226 parsed = [] |
|
3227 for cfg in config: |
|
3228 try: |
|
3229 name, value = cfg.split('=', 1) |
|
3230 section, name = name.split('.', 1) |
|
3231 if not section or not name: |
|
3232 raise IndexError |
|
3233 parsed.append((section, name, value)) |
|
3234 except (IndexError, ValueError): |
|
3235 raise util.Abort(_('malformed --config option: %s') % cfg) |
|
3236 return parsed |
|
3237 |
|
3238 def dispatch(u, args): |
|
3239 extensions.loadall(u) |
|
3240 u.addreadhook(extensions.loadall) |
|
3241 |
|
3242 try: |
|
3243 cmd, func, args, options, cmdoptions = parse(u, args) |
|
3244 except ParseError, inst: |
|
3245 if inst.args[0]: |
|
3246 u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1])) |
|
3247 help_(u, inst.args[0]) |
|
3248 else: |
|
3249 u.warn(_("hg: %s\n") % inst.args[1]) |
|
3250 help_(u, 'shortlist') |
|
3251 return -1 |
|
3252 except AmbiguousCommand, inst: |
|
3253 u.warn(_("hg: command '%s' is ambiguous:\n %s\n") % |
|
3254 (inst.args[0], " ".join(inst.args[1]))) |
|
3255 return -1 |
|
3256 except UnknownCommand, inst: |
|
3257 u.warn(_("hg: unknown command '%s'\n") % inst.args[0]) |
|
3258 help_(u, 'shortlist') |
|
3259 return -1 |
|
3260 |
|
3261 if options["encoding"]: |
|
3262 util._encoding = options["encoding"] |
|
3263 if options["encodingmode"]: |
|
3264 util._encodingmode = options["encodingmode"] |
|
3265 if options["time"]: |
|
3266 def get_times(): |
|
3267 t = os.times() |
|
3268 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock() |
|
3269 t = (t[0], t[1], t[2], t[3], time.clock()) |
|
3270 return t |
|
3271 s = get_times() |
|
3272 def print_time(): |
|
3273 t = get_times() |
|
3274 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") % |
|
3275 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3])) |
|
3276 atexit.register(print_time) |
|
3277 |
|
3278 if options['cwd']: |
|
3279 os.chdir(options['cwd']) |
|
3280 |
|
3281 u.updateopts(options["verbose"], options["debug"], options["quiet"], |
|
3282 not options["noninteractive"], options["traceback"], |
|
3283 parseconfig(options["config"])) |
|
3284 |
|
3285 path = u.expandpath(options["repository"]) or "" |
|
3286 repo = path and hg.repository(u, path=path) or None |
|
3287 if repo and not repo.local(): |
|
3288 raise util.Abort(_("repository '%s' is not local") % path) |
|
3289 |
|
3290 if options['help']: |
|
3291 return help_(u, cmd, options['version']) |
|
3292 elif options['version']: |
|
3293 return version_(u) |
|
3294 elif not cmd: |
|
3295 return help_(u, 'shortlist') |
|
3296 |
|
3297 if cmd not in norepo.split(): |
|
3298 try: |
|
3299 if not repo: |
|
3300 repo = hg.repository(u, path=path) |
|
3301 u = repo.ui |
|
3302 except hg.RepoError: |
|
3303 if cmd not in optionalrepo.split(): |
|
3304 raise |
|
3305 d = lambda: func(u, repo, *args, **cmdoptions) |
|
3306 else: |
|
3307 d = lambda: func(u, *args, **cmdoptions) |
|
3308 |
|
3309 return cmdutil.runcommand(u, options, d) |
|
3310 |