mercurial/commands.py
changeset 4549 0c61124ad877
parent 4548 c9fcebbfc422
child 4558 a73d80d6385a
equal deleted inserted replaced
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