eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/commands.py
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 # commands.py - command processing for mercurial
       
     2 #
       
     3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
       
     4 #
       
     5 # This software may be used and distributed according to the terms of the
       
     6 # GNU General Public License version 2 or any later version.
       
     7 
       
     8 from node import hex, nullid, nullrev, short
       
     9 from lock import release
       
    10 from i18n import _, gettext
       
    11 import os, re, sys, difflib, time, tempfile
       
    12 import hg, util, revlog, extensions, copies, error
       
    13 import patch, help, mdiff, url, encoding, templatekw, discovery
       
    14 import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
       
    15 import merge as mergemod
       
    16 import minirst, revset
       
    17 import dagparser
       
    18 
       
    19 # Commands start here, listed alphabetically
       
    20 
       
    21 def add(ui, repo, *pats, **opts):
       
    22     """add the specified files on the next commit
       
    23 
       
    24     Schedule files to be version controlled and added to the
       
    25     repository.
       
    26 
       
    27     The files will be added to the repository at the next commit. To
       
    28     undo an add before that, see :hg:`forget`.
       
    29 
       
    30     If no names are given, add all files to the repository.
       
    31 
       
    32     .. container:: verbose
       
    33 
       
    34        An example showing how new (unknown) files are added
       
    35        automatically by :hg:`add`::
       
    36 
       
    37          $ ls
       
    38          foo.c
       
    39          $ hg status
       
    40          ? foo.c
       
    41          $ hg add
       
    42          adding foo.c
       
    43          $ hg status
       
    44          A foo.c
       
    45 
       
    46     Returns 0 if all files are successfully added.
       
    47     """
       
    48 
       
    49     m = cmdutil.match(repo, pats, opts)
       
    50     rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
       
    51                            opts.get('subrepos'), prefix="")
       
    52     return rejected and 1 or 0
       
    53 
       
    54 def addremove(ui, repo, *pats, **opts):
       
    55     """add all new files, delete all missing files
       
    56 
       
    57     Add all new files and remove all missing files from the
       
    58     repository.
       
    59 
       
    60     New files are ignored if they match any of the patterns in
       
    61     .hgignore. As with add, these changes take effect at the next
       
    62     commit.
       
    63 
       
    64     Use the -s/--similarity option to detect renamed files. With a
       
    65     parameter greater than 0, this compares every removed file with
       
    66     every added file and records those similar enough as renames. This
       
    67     option takes a percentage between 0 (disabled) and 100 (files must
       
    68     be identical) as its parameter. Detecting renamed files this way
       
    69     can be expensive. After using this option, :hg:`status -C` can be
       
    70     used to check which files were identified as moved or renamed.
       
    71 
       
    72     Returns 0 if all files are successfully added.
       
    73     """
       
    74     try:
       
    75         sim = float(opts.get('similarity') or 100)
       
    76     except ValueError:
       
    77         raise util.Abort(_('similarity must be a number'))
       
    78     if sim < 0 or sim > 100:
       
    79         raise util.Abort(_('similarity must be between 0 and 100'))
       
    80     return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
       
    81 
       
    82 def annotate(ui, repo, *pats, **opts):
       
    83     """show changeset information by line for each file
       
    84 
       
    85     List changes in files, showing the revision id responsible for
       
    86     each line
       
    87 
       
    88     This command is useful for discovering when a change was made and
       
    89     by whom.
       
    90 
       
    91     Without the -a/--text option, annotate will avoid processing files
       
    92     it detects as binary. With -a, annotate will annotate the file
       
    93     anyway, although the results will probably be neither useful
       
    94     nor desirable.
       
    95 
       
    96     Returns 0 on success.
       
    97     """
       
    98     if opts.get('follow'):
       
    99         # --follow is deprecated and now just an alias for -f/--file
       
   100         # to mimic the behavior of Mercurial before version 1.5
       
   101         opts['file'] = 1
       
   102 
       
   103     datefunc = ui.quiet and util.shortdate or util.datestr
       
   104     getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
       
   105 
       
   106     if not pats:
       
   107         raise util.Abort(_('at least one filename or pattern is required'))
       
   108 
       
   109     opmap = [('user', lambda x: ui.shortuser(x[0].user())),
       
   110              ('number', lambda x: str(x[0].rev())),
       
   111              ('changeset', lambda x: short(x[0].node())),
       
   112              ('date', getdate),
       
   113              ('file', lambda x: x[0].path()),
       
   114             ]
       
   115 
       
   116     if (not opts.get('user') and not opts.get('changeset')
       
   117         and not opts.get('date') and not opts.get('file')):
       
   118         opts['number'] = 1
       
   119 
       
   120     linenumber = opts.get('line_number') is not None
       
   121     if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
       
   122         raise util.Abort(_('at least one of -n/-c is required for -l'))
       
   123 
       
   124     funcmap = [func for op, func in opmap if opts.get(op)]
       
   125     if linenumber:
       
   126         lastfunc = funcmap[-1]
       
   127         funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
       
   128 
       
   129     ctx = repo[opts.get('rev')]
       
   130     m = cmdutil.match(repo, pats, opts)
       
   131     follow = not opts.get('no_follow')
       
   132     for abs in ctx.walk(m):
       
   133         fctx = ctx[abs]
       
   134         if not opts.get('text') and util.binary(fctx.data()):
       
   135             ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
       
   136             continue
       
   137 
       
   138         lines = fctx.annotate(follow=follow, linenumber=linenumber)
       
   139         pieces = []
       
   140 
       
   141         for f in funcmap:
       
   142             l = [f(n) for n, dummy in lines]
       
   143             if l:
       
   144                 sized = [(x, encoding.colwidth(x)) for x in l]
       
   145                 ml = max([w for x, w in sized])
       
   146                 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
       
   147 
       
   148         if pieces:
       
   149             for p, l in zip(zip(*pieces), lines):
       
   150                 ui.write("%s: %s" % (" ".join(p), l[1]))
       
   151 
       
   152 def archive(ui, repo, dest, **opts):
       
   153     '''create an unversioned archive of a repository revision
       
   154 
       
   155     By default, the revision used is the parent of the working
       
   156     directory; use -r/--rev to specify a different revision.
       
   157 
       
   158     The archive type is automatically detected based on file
       
   159     extension (or override using -t/--type).
       
   160 
       
   161     Valid types are:
       
   162 
       
   163     :``files``: a directory full of files (default)
       
   164     :``tar``:   tar archive, uncompressed
       
   165     :``tbz2``:  tar archive, compressed using bzip2
       
   166     :``tgz``:   tar archive, compressed using gzip
       
   167     :``uzip``:  zip archive, uncompressed
       
   168     :``zip``:   zip archive, compressed using deflate
       
   169 
       
   170     The exact name of the destination archive or directory is given
       
   171     using a format string; see :hg:`help export` for details.
       
   172 
       
   173     Each member added to an archive file has a directory prefix
       
   174     prepended. Use -p/--prefix to specify a format string for the
       
   175     prefix. The default is the basename of the archive, with suffixes
       
   176     removed.
       
   177 
       
   178     Returns 0 on success.
       
   179     '''
       
   180 
       
   181     ctx = repo[opts.get('rev')]
       
   182     if not ctx:
       
   183         raise util.Abort(_('no working directory: please specify a revision'))
       
   184     node = ctx.node()
       
   185     dest = cmdutil.make_filename(repo, dest, node)
       
   186     if os.path.realpath(dest) == repo.root:
       
   187         raise util.Abort(_('repository root cannot be destination'))
       
   188 
       
   189     kind = opts.get('type') or archival.guesskind(dest) or 'files'
       
   190     prefix = opts.get('prefix')
       
   191 
       
   192     if dest == '-':
       
   193         if kind == 'files':
       
   194             raise util.Abort(_('cannot archive plain files to stdout'))
       
   195         dest = sys.stdout
       
   196         if not prefix:
       
   197             prefix = os.path.basename(repo.root) + '-%h'
       
   198 
       
   199     prefix = cmdutil.make_filename(repo, prefix, node)
       
   200     matchfn = cmdutil.match(repo, [], opts)
       
   201     archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
       
   202                      matchfn, prefix, subrepos=opts.get('subrepos'))
       
   203 
       
   204 def backout(ui, repo, node=None, rev=None, **opts):
       
   205     '''reverse effect of earlier changeset
       
   206 
       
   207     The backout command merges the reverse effect of the reverted
       
   208     changeset into the working directory.
       
   209 
       
   210     With the --merge option, it first commits the reverted changes
       
   211     as a new changeset. This new changeset is a child of the reverted
       
   212     changeset.
       
   213     The --merge option remembers the parent of the working directory
       
   214     before starting the backout, then merges the new head with that
       
   215     changeset afterwards.
       
   216     This will result in an explicit merge in the history.
       
   217 
       
   218     If you backout a changeset other than the original parent of the
       
   219     working directory, the result of this merge is not committed,
       
   220     as with a normal merge. Otherwise, no merge is needed and the
       
   221     commit is automatic.
       
   222 
       
   223     Note that the default behavior (without --merge) has changed in
       
   224     version 1.7. To restore the previous default behavior, use
       
   225     :hg:`backout --merge` and then :hg:`update --clean .` to get rid of
       
   226     the ongoing merge.
       
   227 
       
   228     See :hg:`help dates` for a list of formats valid for -d/--date.
       
   229 
       
   230     Returns 0 on success.
       
   231     '''
       
   232     if rev and node:
       
   233         raise util.Abort(_("please specify just one revision"))
       
   234 
       
   235     if not rev:
       
   236         rev = node
       
   237 
       
   238     if not rev:
       
   239         raise util.Abort(_("please specify a revision to backout"))
       
   240 
       
   241     date = opts.get('date')
       
   242     if date:
       
   243         opts['date'] = util.parsedate(date)
       
   244 
       
   245     cmdutil.bail_if_changed(repo)
       
   246     node = repo.lookup(rev)
       
   247 
       
   248     op1, op2 = repo.dirstate.parents()
       
   249     a = repo.changelog.ancestor(op1, node)
       
   250     if a != node:
       
   251         raise util.Abort(_('cannot backout change on a different branch'))
       
   252 
       
   253     p1, p2 = repo.changelog.parents(node)
       
   254     if p1 == nullid:
       
   255         raise util.Abort(_('cannot backout a change with no parents'))
       
   256     if p2 != nullid:
       
   257         if not opts.get('parent'):
       
   258             raise util.Abort(_('cannot backout a merge changeset without '
       
   259                                '--parent'))
       
   260         p = repo.lookup(opts['parent'])
       
   261         if p not in (p1, p2):
       
   262             raise util.Abort(_('%s is not a parent of %s') %
       
   263                              (short(p), short(node)))
       
   264         parent = p
       
   265     else:
       
   266         if opts.get('parent'):
       
   267             raise util.Abort(_('cannot use --parent on non-merge changeset'))
       
   268         parent = p1
       
   269 
       
   270     # the backout should appear on the same branch
       
   271     branch = repo.dirstate.branch()
       
   272     hg.clean(repo, node, show_stats=False)
       
   273     repo.dirstate.setbranch(branch)
       
   274     revert_opts = opts.copy()
       
   275     revert_opts['date'] = None
       
   276     revert_opts['all'] = True
       
   277     revert_opts['rev'] = hex(parent)
       
   278     revert_opts['no_backup'] = None
       
   279     revert(ui, repo, **revert_opts)
       
   280     if not opts.get('merge') and op1 != node:
       
   281         try:
       
   282             ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
       
   283             return hg.update(repo, op1)
       
   284         finally:
       
   285             ui.setconfig('ui', 'forcemerge', '')
       
   286 
       
   287     commit_opts = opts.copy()
       
   288     commit_opts['addremove'] = False
       
   289     if not commit_opts['message'] and not commit_opts['logfile']:
       
   290         # we don't translate commit messages
       
   291         commit_opts['message'] = "Backed out changeset %s" % short(node)
       
   292         commit_opts['force_editor'] = True
       
   293     commit(ui, repo, **commit_opts)
       
   294     def nice(node):
       
   295         return '%d:%s' % (repo.changelog.rev(node), short(node))
       
   296     ui.status(_('changeset %s backs out changeset %s\n') %
       
   297               (nice(repo.changelog.tip()), nice(node)))
       
   298     if opts.get('merge') and op1 != node:
       
   299         hg.clean(repo, op1, show_stats=False)
       
   300         ui.status(_('merging with changeset %s\n')
       
   301                   % nice(repo.changelog.tip()))
       
   302         try:
       
   303             ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
       
   304             return hg.merge(repo, hex(repo.changelog.tip()))
       
   305         finally:
       
   306             ui.setconfig('ui', 'forcemerge', '')
       
   307     return 0
       
   308 
       
   309 def bisect(ui, repo, rev=None, extra=None, command=None,
       
   310                reset=None, good=None, bad=None, skip=None, noupdate=None):
       
   311     """subdivision search of changesets
       
   312 
       
   313     This command helps to find changesets which introduce problems. To
       
   314     use, mark the earliest changeset you know exhibits the problem as
       
   315     bad, then mark the latest changeset which is free from the problem
       
   316     as good. Bisect will update your working directory to a revision
       
   317     for testing (unless the -U/--noupdate option is specified). Once
       
   318     you have performed tests, mark the working directory as good or
       
   319     bad, and bisect will either update to another candidate changeset
       
   320     or announce that it has found the bad revision.
       
   321 
       
   322     As a shortcut, you can also use the revision argument to mark a
       
   323     revision as good or bad without checking it out first.
       
   324 
       
   325     If you supply a command, it will be used for automatic bisection.
       
   326     Its exit status will be used to mark revisions as good or bad:
       
   327     status 0 means good, 125 means to skip the revision, 127
       
   328     (command not found) will abort the bisection, and any other
       
   329     non-zero exit status means the revision is bad.
       
   330 
       
   331     Returns 0 on success.
       
   332     """
       
   333     def print_result(nodes, good):
       
   334         displayer = cmdutil.show_changeset(ui, repo, {})
       
   335         if len(nodes) == 1:
       
   336             # narrowed it down to a single revision
       
   337             if good:
       
   338                 ui.write(_("The first good revision is:\n"))
       
   339             else:
       
   340                 ui.write(_("The first bad revision is:\n"))
       
   341             displayer.show(repo[nodes[0]])
       
   342             parents = repo[nodes[0]].parents()
       
   343             if len(parents) > 1:
       
   344                 side = good and state['bad'] or state['good']
       
   345                 num = len(set(i.node() for i in parents) & set(side))
       
   346                 if num == 1:
       
   347                     common = parents[0].ancestor(parents[1])
       
   348                     ui.write(_('Not all ancestors of this changeset have been'
       
   349                                ' checked.\nTo check the other ancestors, start'
       
   350                                ' from the common ancestor, %s.\n' % common))
       
   351         else:
       
   352             # multiple possible revisions
       
   353             if good:
       
   354                 ui.write(_("Due to skipped revisions, the first "
       
   355                         "good revision could be any of:\n"))
       
   356             else:
       
   357                 ui.write(_("Due to skipped revisions, the first "
       
   358                         "bad revision could be any of:\n"))
       
   359             for n in nodes:
       
   360                 displayer.show(repo[n])
       
   361         displayer.close()
       
   362 
       
   363     def check_state(state, interactive=True):
       
   364         if not state['good'] or not state['bad']:
       
   365             if (good or bad or skip or reset) and interactive:
       
   366                 return
       
   367             if not state['good']:
       
   368                 raise util.Abort(_('cannot bisect (no known good revisions)'))
       
   369             else:
       
   370                 raise util.Abort(_('cannot bisect (no known bad revisions)'))
       
   371         return True
       
   372 
       
   373     # backward compatibility
       
   374     if rev in "good bad reset init".split():
       
   375         ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
       
   376         cmd, rev, extra = rev, extra, None
       
   377         if cmd == "good":
       
   378             good = True
       
   379         elif cmd == "bad":
       
   380             bad = True
       
   381         else:
       
   382             reset = True
       
   383     elif extra or good + bad + skip + reset + bool(command) > 1:
       
   384         raise util.Abort(_('incompatible arguments'))
       
   385 
       
   386     if reset:
       
   387         p = repo.join("bisect.state")
       
   388         if os.path.exists(p):
       
   389             os.unlink(p)
       
   390         return
       
   391 
       
   392     state = hbisect.load_state(repo)
       
   393 
       
   394     if command:
       
   395         changesets = 1
       
   396         try:
       
   397             while changesets:
       
   398                 # update state
       
   399                 status = util.system(command)
       
   400                 if status == 125:
       
   401                     transition = "skip"
       
   402                 elif status == 0:
       
   403                     transition = "good"
       
   404                 # status < 0 means process was killed
       
   405                 elif status == 127:
       
   406                     raise util.Abort(_("failed to execute %s") % command)
       
   407                 elif status < 0:
       
   408                     raise util.Abort(_("%s killed") % command)
       
   409                 else:
       
   410                     transition = "bad"
       
   411                 ctx = repo[rev or '.']
       
   412                 state[transition].append(ctx.node())
       
   413                 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
       
   414                 check_state(state, interactive=False)
       
   415                 # bisect
       
   416                 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
       
   417                 # update to next check
       
   418                 cmdutil.bail_if_changed(repo)
       
   419                 hg.clean(repo, nodes[0], show_stats=False)
       
   420         finally:
       
   421             hbisect.save_state(repo, state)
       
   422         print_result(nodes, good)
       
   423         return
       
   424 
       
   425     # update state
       
   426 
       
   427     if rev:
       
   428         nodes = [repo.lookup(i) for i in cmdutil.revrange(repo, [rev])]
       
   429     else:
       
   430         nodes = [repo.lookup('.')]
       
   431 
       
   432     if good or bad or skip:
       
   433         if good:
       
   434             state['good'] += nodes
       
   435         elif bad:
       
   436             state['bad'] += nodes
       
   437         elif skip:
       
   438             state['skip'] += nodes
       
   439         hbisect.save_state(repo, state)
       
   440 
       
   441     if not check_state(state):
       
   442         return
       
   443 
       
   444     # actually bisect
       
   445     nodes, changesets, good = hbisect.bisect(repo.changelog, state)
       
   446     if changesets == 0:
       
   447         print_result(nodes, good)
       
   448     else:
       
   449         assert len(nodes) == 1 # only a single node can be tested next
       
   450         node = nodes[0]
       
   451         # compute the approximate number of remaining tests
       
   452         tests, size = 0, 2
       
   453         while size <= changesets:
       
   454             tests, size = tests + 1, size * 2
       
   455         rev = repo.changelog.rev(node)
       
   456         ui.write(_("Testing changeset %d:%s "
       
   457                    "(%d changesets remaining, ~%d tests)\n")
       
   458                  % (rev, short(node), changesets, tests))
       
   459         if not noupdate:
       
   460             cmdutil.bail_if_changed(repo)
       
   461             return hg.clean(repo, node)
       
   462 
       
   463 def branch(ui, repo, label=None, **opts):
       
   464     """set or show the current branch name
       
   465 
       
   466     With no argument, show the current branch name. With one argument,
       
   467     set the working directory branch name (the branch will not exist
       
   468     in the repository until the next commit). Standard practice
       
   469     recommends that primary development take place on the 'default'
       
   470     branch.
       
   471 
       
   472     Unless -f/--force is specified, branch will not let you set a
       
   473     branch name that already exists, even if it's inactive.
       
   474 
       
   475     Use -C/--clean to reset the working directory branch to that of
       
   476     the parent of the working directory, negating a previous branch
       
   477     change.
       
   478 
       
   479     Use the command :hg:`update` to switch to an existing branch. Use
       
   480     :hg:`commit --close-branch` to mark this branch as closed.
       
   481 
       
   482     Returns 0 on success.
       
   483     """
       
   484 
       
   485     if opts.get('clean'):
       
   486         label = repo[None].parents()[0].branch()
       
   487         repo.dirstate.setbranch(label)
       
   488         ui.status(_('reset working directory to branch %s\n') % label)
       
   489     elif label:
       
   490         utflabel = encoding.fromlocal(label)
       
   491         if not opts.get('force') and utflabel in repo.branchtags():
       
   492             if label not in [p.branch() for p in repo.parents()]:
       
   493                 raise util.Abort(_('a branch of the same name already exists'
       
   494                                    " (use 'hg update' to switch to it)"))
       
   495         repo.dirstate.setbranch(utflabel)
       
   496         ui.status(_('marked working directory as branch %s\n') % label)
       
   497     else:
       
   498         ui.write("%s\n" % encoding.tolocal(repo.dirstate.branch()))
       
   499 
       
   500 def branches(ui, repo, active=False, closed=False):
       
   501     """list repository named branches
       
   502 
       
   503     List the repository's named branches, indicating which ones are
       
   504     inactive. If -c/--closed is specified, also list branches which have
       
   505     been marked closed (see :hg:`commit --close-branch`).
       
   506 
       
   507     If -a/--active is specified, only show active branches. A branch
       
   508     is considered active if it contains repository heads.
       
   509 
       
   510     Use the command :hg:`update` to switch to an existing branch.
       
   511 
       
   512     Returns 0.
       
   513     """
       
   514 
       
   515     hexfunc = ui.debugflag and hex or short
       
   516     activebranches = [repo[n].branch() for n in repo.heads()]
       
   517     def testactive(tag, node):
       
   518         realhead = tag in activebranches
       
   519         open = node in repo.branchheads(tag, closed=False)
       
   520         return realhead and open
       
   521     branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
       
   522                           for tag, node in repo.branchtags().items()],
       
   523                       reverse=True)
       
   524 
       
   525     for isactive, node, tag in branches:
       
   526         if (not active) or isactive:
       
   527             encodedtag = encoding.tolocal(tag)
       
   528             if ui.quiet:
       
   529                 ui.write("%s\n" % encodedtag)
       
   530             else:
       
   531                 hn = repo.lookup(node)
       
   532                 if isactive:
       
   533                     label = 'branches.active'
       
   534                     notice = ''
       
   535                 elif hn not in repo.branchheads(tag, closed=False):
       
   536                     if not closed:
       
   537                         continue
       
   538                     label = 'branches.closed'
       
   539                     notice = _(' (closed)')
       
   540                 else:
       
   541                     label = 'branches.inactive'
       
   542                     notice = _(' (inactive)')
       
   543                 if tag == repo.dirstate.branch():
       
   544                     label = 'branches.current'
       
   545                 rev = str(node).rjust(31 - encoding.colwidth(encodedtag))
       
   546                 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
       
   547                 encodedtag = ui.label(encodedtag, label)
       
   548                 ui.write("%s %s%s\n" % (encodedtag, rev, notice))
       
   549 
       
   550 def bundle(ui, repo, fname, dest=None, **opts):
       
   551     """create a changegroup file
       
   552 
       
   553     Generate a compressed changegroup file collecting changesets not
       
   554     known to be in another repository.
       
   555 
       
   556     If you omit the destination repository, then hg assumes the
       
   557     destination will have all the nodes you specify with --base
       
   558     parameters. To create a bundle containing all changesets, use
       
   559     -a/--all (or --base null).
       
   560 
       
   561     You can change compression method with the -t/--type option.
       
   562     The available compression methods are: none, bzip2, and
       
   563     gzip (by default, bundles are compressed using bzip2).
       
   564 
       
   565     The bundle file can then be transferred using conventional means
       
   566     and applied to another repository with the unbundle or pull
       
   567     command. This is useful when direct push and pull are not
       
   568     available or when exporting an entire repository is undesirable.
       
   569 
       
   570     Applying bundles preserves all changeset contents including
       
   571     permissions, copy/rename information, and revision history.
       
   572 
       
   573     Returns 0 on success, 1 if no changes found.
       
   574     """
       
   575     revs = opts.get('rev') or None
       
   576     if opts.get('all'):
       
   577         base = ['null']
       
   578     else:
       
   579         base = opts.get('base')
       
   580     if base:
       
   581         if dest:
       
   582             raise util.Abort(_("--base is incompatible with specifying "
       
   583                                "a destination"))
       
   584         base = [repo.lookup(rev) for rev in base]
       
   585         # create the right base
       
   586         # XXX: nodesbetween / changegroup* should be "fixed" instead
       
   587         o = []
       
   588         has = set((nullid,))
       
   589         for n in base:
       
   590             has.update(repo.changelog.reachable(n))
       
   591         if revs:
       
   592             revs = [repo.lookup(rev) for rev in revs]
       
   593             visit = revs[:]
       
   594             has.difference_update(visit)
       
   595         else:
       
   596             visit = repo.changelog.heads()
       
   597         seen = {}
       
   598         while visit:
       
   599             n = visit.pop(0)
       
   600             parents = [p for p in repo.changelog.parents(n) if p not in has]
       
   601             if len(parents) == 0:
       
   602                 if n not in has:
       
   603                     o.append(n)
       
   604             else:
       
   605                 for p in parents:
       
   606                     if p not in seen:
       
   607                         seen[p] = 1
       
   608                         visit.append(p)
       
   609     else:
       
   610         dest = ui.expandpath(dest or 'default-push', dest or 'default')
       
   611         dest, branches = hg.parseurl(dest, opts.get('branch'))
       
   612         other = hg.repository(hg.remoteui(repo, opts), dest)
       
   613         revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
       
   614         if revs:
       
   615             revs = [repo.lookup(rev) for rev in revs]
       
   616         o = discovery.findoutgoing(repo, other, force=opts.get('force'))
       
   617 
       
   618     if not o:
       
   619         ui.status(_("no changes found\n"))
       
   620         return 1
       
   621 
       
   622     if revs:
       
   623         cg = repo.changegroupsubset(o, revs, 'bundle')
       
   624     else:
       
   625         cg = repo.changegroup(o, 'bundle')
       
   626 
       
   627     bundletype = opts.get('type', 'bzip2').lower()
       
   628     btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
       
   629     bundletype = btypes.get(bundletype)
       
   630     if bundletype not in changegroup.bundletypes:
       
   631         raise util.Abort(_('unknown bundle type specified with --type'))
       
   632 
       
   633     changegroup.writebundle(cg, fname, bundletype)
       
   634 
       
   635 def cat(ui, repo, file1, *pats, **opts):
       
   636     """output the current or given revision of files
       
   637 
       
   638     Print the specified files as they were at the given revision. If
       
   639     no revision is given, the parent of the working directory is used,
       
   640     or tip if no revision is checked out.
       
   641 
       
   642     Output may be to a file, in which case the name of the file is
       
   643     given using a format string. The formatting rules are the same as
       
   644     for the export command, with the following additions:
       
   645 
       
   646     :``%s``: basename of file being printed
       
   647     :``%d``: dirname of file being printed, or '.' if in repository root
       
   648     :``%p``: root-relative path name of file being printed
       
   649 
       
   650     Returns 0 on success.
       
   651     """
       
   652     ctx = cmdutil.revsingle(repo, opts.get('rev'))
       
   653     err = 1
       
   654     m = cmdutil.match(repo, (file1,) + pats, opts)
       
   655     for abs in ctx.walk(m):
       
   656         fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
       
   657         data = ctx[abs].data()
       
   658         if opts.get('decode'):
       
   659             data = repo.wwritedata(abs, data)
       
   660         fp.write(data)
       
   661         err = 0
       
   662     return err
       
   663 
       
   664 def clone(ui, source, dest=None, **opts):
       
   665     """make a copy of an existing repository
       
   666 
       
   667     Create a copy of an existing repository in a new directory.
       
   668 
       
   669     If no destination directory name is specified, it defaults to the
       
   670     basename of the source.
       
   671 
       
   672     The location of the source is added to the new repository's
       
   673     .hg/hgrc file, as the default to be used for future pulls.
       
   674 
       
   675     See :hg:`help urls` for valid source format details.
       
   676 
       
   677     It is possible to specify an ``ssh://`` URL as the destination, but no
       
   678     .hg/hgrc and working directory will be created on the remote side.
       
   679     Please see :hg:`help urls` for important details about ``ssh://`` URLs.
       
   680 
       
   681     A set of changesets (tags, or branch names) to pull may be specified
       
   682     by listing each changeset (tag, or branch name) with -r/--rev.
       
   683     If -r/--rev is used, the cloned repository will contain only a subset
       
   684     of the changesets of the source repository. Only the set of changesets
       
   685     defined by all -r/--rev options (including all their ancestors)
       
   686     will be pulled into the destination repository.
       
   687     No subsequent changesets (including subsequent tags) will be present
       
   688     in the destination.
       
   689 
       
   690     Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
       
   691     local source repositories.
       
   692 
       
   693     For efficiency, hardlinks are used for cloning whenever the source
       
   694     and destination are on the same filesystem (note this applies only
       
   695     to the repository data, not to the working directory). Some
       
   696     filesystems, such as AFS, implement hardlinking incorrectly, but
       
   697     do not report errors. In these cases, use the --pull option to
       
   698     avoid hardlinking.
       
   699 
       
   700     In some cases, you can clone repositories and the working directory
       
   701     using full hardlinks with ::
       
   702 
       
   703       $ cp -al REPO REPOCLONE
       
   704 
       
   705     This is the fastest way to clone, but it is not always safe. The
       
   706     operation is not atomic (making sure REPO is not modified during
       
   707     the operation is up to you) and you have to make sure your editor
       
   708     breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
       
   709     this is not compatible with certain extensions that place their
       
   710     metadata under the .hg directory, such as mq.
       
   711 
       
   712     Mercurial will update the working directory to the first applicable
       
   713     revision from this list:
       
   714 
       
   715     a) null if -U or the source repository has no changesets
       
   716     b) if -u . and the source repository is local, the first parent of
       
   717        the source repository's working directory
       
   718     c) the changeset specified with -u (if a branch name, this means the
       
   719        latest head of that branch)
       
   720     d) the changeset specified with -r
       
   721     e) the tipmost head specified with -b
       
   722     f) the tipmost head specified with the url#branch source syntax
       
   723     g) the tipmost head of the default branch
       
   724     h) tip
       
   725 
       
   726     Returns 0 on success.
       
   727     """
       
   728     if opts.get('noupdate') and opts.get('updaterev'):
       
   729         raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
       
   730 
       
   731     r = hg.clone(hg.remoteui(ui, opts), source, dest,
       
   732                  pull=opts.get('pull'),
       
   733                  stream=opts.get('uncompressed'),
       
   734                  rev=opts.get('rev'),
       
   735                  update=opts.get('updaterev') or not opts.get('noupdate'),
       
   736                  branch=opts.get('branch'))
       
   737 
       
   738     return r is None
       
   739 
       
   740 def commit(ui, repo, *pats, **opts):
       
   741     """commit the specified files or all outstanding changes
       
   742 
       
   743     Commit changes to the given files into the repository. Unlike a
       
   744     centralized RCS, this operation is a local operation. See
       
   745     :hg:`push` for a way to actively distribute your changes.
       
   746 
       
   747     If a list of files is omitted, all changes reported by :hg:`status`
       
   748     will be committed.
       
   749 
       
   750     If you are committing the result of a merge, do not provide any
       
   751     filenames or -I/-X filters.
       
   752 
       
   753     If no commit message is specified, Mercurial starts your
       
   754     configured editor where you can enter a message. In case your
       
   755     commit fails, you will find a backup of your message in
       
   756     ``.hg/last-message.txt``.
       
   757 
       
   758     See :hg:`help dates` for a list of formats valid for -d/--date.
       
   759 
       
   760     Returns 0 on success, 1 if nothing changed.
       
   761     """
       
   762     extra = {}
       
   763     if opts.get('close_branch'):
       
   764         if repo['.'].node() not in repo.branchheads():
       
   765             # The topo heads set is included in the branch heads set of the
       
   766             # current branch, so it's sufficient to test branchheads
       
   767             raise util.Abort(_('can only close branch heads'))
       
   768         extra['close'] = 1
       
   769     e = cmdutil.commiteditor
       
   770     if opts.get('force_editor'):
       
   771         e = cmdutil.commitforceeditor
       
   772 
       
   773     def commitfunc(ui, repo, message, match, opts):
       
   774         return repo.commit(message, opts.get('user'), opts.get('date'), match,
       
   775                            editor=e, extra=extra)
       
   776 
       
   777     branch = repo[None].branch()
       
   778     bheads = repo.branchheads(branch)
       
   779 
       
   780     node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
       
   781     if not node:
       
   782         ui.status(_("nothing changed\n"))
       
   783         return 1
       
   784 
       
   785     ctx = repo[node]
       
   786     parents = ctx.parents()
       
   787 
       
   788     if bheads and not [x for x in parents
       
   789                        if x.node() in bheads and x.branch() == branch]:
       
   790         ui.status(_('created new head\n'))
       
   791         # The message is not printed for initial roots. For the other
       
   792         # changesets, it is printed in the following situations:
       
   793         #
       
   794         # Par column: for the 2 parents with ...
       
   795         #   N: null or no parent
       
   796         #   B: parent is on another named branch
       
   797         #   C: parent is a regular non head changeset
       
   798         #   H: parent was a branch head of the current branch
       
   799         # Msg column: whether we print "created new head" message
       
   800         # In the following, it is assumed that there already exists some
       
   801         # initial branch heads of the current branch, otherwise nothing is
       
   802         # printed anyway.
       
   803         #
       
   804         # Par Msg Comment
       
   805         # NN   y  additional topo root
       
   806         #
       
   807         # BN   y  additional branch root
       
   808         # CN   y  additional topo head
       
   809         # HN   n  usual case
       
   810         #
       
   811         # BB   y  weird additional branch root
       
   812         # CB   y  branch merge
       
   813         # HB   n  merge with named branch
       
   814         #
       
   815         # CC   y  additional head from merge
       
   816         # CH   n  merge with a head
       
   817         #
       
   818         # HH   n  head merge: head count decreases
       
   819 
       
   820     if not opts.get('close_branch'):
       
   821         for r in parents:
       
   822             if r.extra().get('close') and r.branch() == branch:
       
   823                 ui.status(_('reopening closed branch head %d\n') % r)
       
   824 
       
   825     if ui.debugflag:
       
   826         ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
       
   827     elif ui.verbose:
       
   828         ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
       
   829 
       
   830 def copy(ui, repo, *pats, **opts):
       
   831     """mark files as copied for the next commit
       
   832 
       
   833     Mark dest as having copies of source files. If dest is a
       
   834     directory, copies are put in that directory. If dest is a file,
       
   835     the source must be a single file.
       
   836 
       
   837     By default, this command copies the contents of files as they
       
   838     exist in the working directory. If invoked with -A/--after, the
       
   839     operation is recorded, but no copying is performed.
       
   840 
       
   841     This command takes effect with the next commit. To undo a copy
       
   842     before that, see :hg:`revert`.
       
   843 
       
   844     Returns 0 on success, 1 if errors are encountered.
       
   845     """
       
   846     wlock = repo.wlock(False)
       
   847     try:
       
   848         return cmdutil.copy(ui, repo, pats, opts)
       
   849     finally:
       
   850         wlock.release()
       
   851 
       
   852 def debugancestor(ui, repo, *args):
       
   853     """find the ancestor revision of two revisions in a given index"""
       
   854     if len(args) == 3:
       
   855         index, rev1, rev2 = args
       
   856         r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
       
   857         lookup = r.lookup
       
   858     elif len(args) == 2:
       
   859         if not repo:
       
   860             raise util.Abort(_("there is no Mercurial repository here "
       
   861                                "(.hg not found)"))
       
   862         rev1, rev2 = args
       
   863         r = repo.changelog
       
   864         lookup = repo.lookup
       
   865     else:
       
   866         raise util.Abort(_('either two or three arguments required'))
       
   867     a = r.ancestor(lookup(rev1), lookup(rev2))
       
   868     ui.write("%d:%s\n" % (r.rev(a), hex(a)))
       
   869 
       
   870 def debugbuilddag(ui, repo, text,
       
   871                   mergeable_file=False,
       
   872                   appended_file=False,
       
   873                   overwritten_file=False,
       
   874                   new_file=False):
       
   875     """builds a repo with a given dag from scratch in the current empty repo
       
   876 
       
   877     Elements:
       
   878 
       
   879      - "+n" is a linear run of n nodes based on the current default parent
       
   880      - "." is a single node based on the current default parent
       
   881      - "$" resets the default parent to null (implied at the start);
       
   882            otherwise the default parent is always the last node created
       
   883      - "<p" sets the default parent to the backref p
       
   884      - "*p" is a fork at parent p, which is a backref
       
   885      - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
       
   886      - "/p2" is a merge of the preceding node and p2
       
   887      - ":tag" defines a local tag for the preceding node
       
   888      - "@branch" sets the named branch for subsequent nodes
       
   889      - "!command" runs the command using your shell
       
   890      - "!!my command\\n" is like "!", but to the end of the line
       
   891      - "#...\\n" is a comment up to the end of the line
       
   892 
       
   893     Whitespace between the above elements is ignored.
       
   894 
       
   895     A backref is either
       
   896 
       
   897      - a number n, which references the node curr-n, where curr is the current
       
   898        node, or
       
   899      - the name of a local tag you placed earlier using ":tag", or
       
   900      - empty to denote the default parent.
       
   901 
       
   902     All string valued-elements are either strictly alphanumeric, or must
       
   903     be enclosed in double quotes ("..."), with "\\" as escape character.
       
   904 
       
   905     Note that the --overwritten-file and --appended-file options imply the
       
   906     use of "HGMERGE=internal:local" during DAG buildup.
       
   907     """
       
   908 
       
   909     if not (mergeable_file or appended_file or overwritten_file or new_file):
       
   910         raise util.Abort(_('need at least one of -m, -a, -o, -n'))
       
   911 
       
   912     if len(repo.changelog) > 0:
       
   913         raise util.Abort(_('repository is not empty'))
       
   914 
       
   915     if overwritten_file or appended_file:
       
   916         # we don't want to fail in merges during buildup
       
   917         os.environ['HGMERGE'] = 'internal:local'
       
   918 
       
   919     def writefile(fname, text, fmode="wb"):
       
   920         f = open(fname, fmode)
       
   921         try:
       
   922             f.write(text)
       
   923         finally:
       
   924             f.close()
       
   925 
       
   926     if mergeable_file:
       
   927         linesperrev = 2
       
   928         # determine number of revs in DAG
       
   929         n = 0
       
   930         for type, data in dagparser.parsedag(text):
       
   931             if type == 'n':
       
   932                 n += 1
       
   933         # make a file with k lines per rev
       
   934         writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
       
   935                   + "\n")
       
   936 
       
   937     at = -1
       
   938     atbranch = 'default'
       
   939     for type, data in dagparser.parsedag(text):
       
   940         if type == 'n':
       
   941             ui.status('node %s\n' % str(data))
       
   942             id, ps = data
       
   943             p1 = ps[0]
       
   944             if p1 != at:
       
   945                 update(ui, repo, node=str(p1), clean=True)
       
   946                 at = p1
       
   947             if repo.dirstate.branch() != atbranch:
       
   948                 branch(ui, repo, atbranch, force=True)
       
   949             if len(ps) > 1:
       
   950                 p2 = ps[1]
       
   951                 merge(ui, repo, node=p2)
       
   952 
       
   953             if mergeable_file:
       
   954                 f = open("mf", "rb+")
       
   955                 try:
       
   956                     lines = f.read().split("\n")
       
   957                     lines[id * linesperrev] += " r%i" % id
       
   958                     f.seek(0)
       
   959                     f.write("\n".join(lines))
       
   960                 finally:
       
   961                     f.close()
       
   962 
       
   963             if appended_file:
       
   964                 writefile("af", "r%i\n" % id, "ab")
       
   965 
       
   966             if overwritten_file:
       
   967                 writefile("of", "r%i\n" % id)
       
   968 
       
   969             if new_file:
       
   970                 writefile("nf%i" % id, "r%i\n" % id)
       
   971 
       
   972             commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
       
   973             at = id
       
   974         elif type == 'l':
       
   975             id, name = data
       
   976             ui.status('tag %s\n' % name)
       
   977             tag(ui, repo, name, local=True)
       
   978         elif type == 'a':
       
   979             ui.status('branch %s\n' % data)
       
   980             atbranch = data
       
   981         elif type in 'cC':
       
   982             r = util.system(data, cwd=repo.root)
       
   983             if r:
       
   984                 desc, r = util.explain_exit(r)
       
   985                 raise util.Abort(_('%s command %s') % (data, desc))
       
   986 
       
   987 def debugcommands(ui, cmd='', *args):
       
   988     """list all available commands and options"""
       
   989     for cmd, vals in sorted(table.iteritems()):
       
   990         cmd = cmd.split('|')[0].strip('^')
       
   991         opts = ', '.join([i[1] for i in vals[1]])
       
   992         ui.write('%s: %s\n' % (cmd, opts))
       
   993 
       
   994 def debugcomplete(ui, cmd='', **opts):
       
   995     """returns the completion list associated with the given command"""
       
   996 
       
   997     if opts.get('options'):
       
   998         options = []
       
   999         otables = [globalopts]
       
  1000         if cmd:
       
  1001             aliases, entry = cmdutil.findcmd(cmd, table, False)
       
  1002             otables.append(entry[1])
       
  1003         for t in otables:
       
  1004             for o in t:
       
  1005                 if "(DEPRECATED)" in o[3]:
       
  1006                     continue
       
  1007                 if o[0]:
       
  1008                     options.append('-%s' % o[0])
       
  1009                 options.append('--%s' % o[1])
       
  1010         ui.write("%s\n" % "\n".join(options))
       
  1011         return
       
  1012 
       
  1013     cmdlist = cmdutil.findpossible(cmd, table)
       
  1014     if ui.verbose:
       
  1015         cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
       
  1016     ui.write("%s\n" % "\n".join(sorted(cmdlist)))
       
  1017 
       
  1018 def debugfsinfo(ui, path = "."):
       
  1019     """show information detected about current filesystem"""
       
  1020     open('.debugfsinfo', 'w').write('')
       
  1021     ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
       
  1022     ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
       
  1023     ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
       
  1024                                 and 'yes' or 'no'))
       
  1025     os.unlink('.debugfsinfo')
       
  1026 
       
  1027 def debugrebuildstate(ui, repo, rev="tip"):
       
  1028     """rebuild the dirstate as it would look like for the given revision"""
       
  1029     ctx = repo[rev]
       
  1030     wlock = repo.wlock()
       
  1031     try:
       
  1032         repo.dirstate.rebuild(ctx.node(), ctx.manifest())
       
  1033     finally:
       
  1034         wlock.release()
       
  1035 
       
  1036 def debugcheckstate(ui, repo):
       
  1037     """validate the correctness of the current dirstate"""
       
  1038     parent1, parent2 = repo.dirstate.parents()
       
  1039     m1 = repo[parent1].manifest()
       
  1040     m2 = repo[parent2].manifest()
       
  1041     errors = 0
       
  1042     for f in repo.dirstate:
       
  1043         state = repo.dirstate[f]
       
  1044         if state in "nr" and f not in m1:
       
  1045             ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
       
  1046             errors += 1
       
  1047         if state in "a" and f in m1:
       
  1048             ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
       
  1049             errors += 1
       
  1050         if state in "m" and f not in m1 and f not in m2:
       
  1051             ui.warn(_("%s in state %s, but not in either manifest\n") %
       
  1052                     (f, state))
       
  1053             errors += 1
       
  1054     for f in m1:
       
  1055         state = repo.dirstate[f]
       
  1056         if state not in "nrm":
       
  1057             ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
       
  1058             errors += 1
       
  1059     if errors:
       
  1060         error = _(".hg/dirstate inconsistent with current parent's manifest")
       
  1061         raise util.Abort(error)
       
  1062 
       
  1063 def showconfig(ui, repo, *values, **opts):
       
  1064     """show combined config settings from all hgrc files
       
  1065 
       
  1066     With no arguments, print names and values of all config items.
       
  1067 
       
  1068     With one argument of the form section.name, print just the value
       
  1069     of that config item.
       
  1070 
       
  1071     With multiple arguments, print names and values of all config
       
  1072     items with matching section names.
       
  1073 
       
  1074     With --debug, the source (filename and line number) is printed
       
  1075     for each config item.
       
  1076 
       
  1077     Returns 0 on success.
       
  1078     """
       
  1079 
       
  1080     for f in util.rcpath():
       
  1081         ui.debug(_('read config from: %s\n') % f)
       
  1082     untrusted = bool(opts.get('untrusted'))
       
  1083     if values:
       
  1084         sections = [v for v in values if '.' not in v]
       
  1085         items = [v for v in values if '.' in v]
       
  1086         if len(items) > 1 or items and sections:
       
  1087             raise util.Abort(_('only one config item permitted'))
       
  1088     for section, name, value in ui.walkconfig(untrusted=untrusted):
       
  1089         sectname = section + '.' + name
       
  1090         if values:
       
  1091             for v in values:
       
  1092                 if v == section:
       
  1093                     ui.debug('%s: ' %
       
  1094                              ui.configsource(section, name, untrusted))
       
  1095                     ui.write('%s=%s\n' % (sectname, value))
       
  1096                 elif v == sectname:
       
  1097                     ui.debug('%s: ' %
       
  1098                              ui.configsource(section, name, untrusted))
       
  1099                     ui.write(value, '\n')
       
  1100         else:
       
  1101             ui.debug('%s: ' %
       
  1102                      ui.configsource(section, name, untrusted))
       
  1103             ui.write('%s=%s\n' % (sectname, value))
       
  1104 
       
  1105 def debugpushkey(ui, repopath, namespace, *keyinfo):
       
  1106     '''access the pushkey key/value protocol
       
  1107 
       
  1108     With two args, list the keys in the given namespace.
       
  1109 
       
  1110     With five args, set a key to new if it currently is set to old.
       
  1111     Reports success or failure.
       
  1112     '''
       
  1113 
       
  1114     target = hg.repository(ui, repopath)
       
  1115     if keyinfo:
       
  1116         key, old, new = keyinfo
       
  1117         r = target.pushkey(namespace, key, old, new)
       
  1118         ui.status(str(r) + '\n')
       
  1119         return not(r)
       
  1120     else:
       
  1121         for k, v in target.listkeys(namespace).iteritems():
       
  1122             ui.write("%s\t%s\n" % (k.encode('string-escape'),
       
  1123                                    v.encode('string-escape')))
       
  1124 
       
  1125 def debugrevspec(ui, repo, expr):
       
  1126     '''parse and apply a revision specification'''
       
  1127     if ui.verbose:
       
  1128         tree = revset.parse(expr)
       
  1129         ui.note(tree, "\n")
       
  1130     func = revset.match(expr)
       
  1131     for c in func(repo, range(len(repo))):
       
  1132         ui.write("%s\n" % c)
       
  1133 
       
  1134 def debugsetparents(ui, repo, rev1, rev2=None):
       
  1135     """manually set the parents of the current working directory
       
  1136 
       
  1137     This is useful for writing repository conversion tools, but should
       
  1138     be used with care.
       
  1139 
       
  1140     Returns 0 on success.
       
  1141     """
       
  1142 
       
  1143     if not rev2:
       
  1144         rev2 = hex(nullid)
       
  1145 
       
  1146     wlock = repo.wlock()
       
  1147     try:
       
  1148         repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
       
  1149     finally:
       
  1150         wlock.release()
       
  1151 
       
  1152 def debugstate(ui, repo, nodates=None):
       
  1153     """show the contents of the current dirstate"""
       
  1154     timestr = ""
       
  1155     showdate = not nodates
       
  1156     for file_, ent in sorted(repo.dirstate._map.iteritems()):
       
  1157         if showdate:
       
  1158             if ent[3] == -1:
       
  1159                 # Pad or slice to locale representation
       
  1160                 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
       
  1161                                                time.localtime(0)))
       
  1162                 timestr = 'unset'
       
  1163                 timestr = (timestr[:locale_len] +
       
  1164                            ' ' * (locale_len - len(timestr)))
       
  1165             else:
       
  1166                 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
       
  1167                                         time.localtime(ent[3]))
       
  1168         if ent[1] & 020000:
       
  1169             mode = 'lnk'
       
  1170         else:
       
  1171             mode = '%3o' % (ent[1] & 0777)
       
  1172         ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
       
  1173     for f in repo.dirstate.copies():
       
  1174         ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
       
  1175 
       
  1176 def debugsub(ui, repo, rev=None):
       
  1177     if rev == '':
       
  1178         rev = None
       
  1179     for k, v in sorted(repo[rev].substate.items()):
       
  1180         ui.write('path %s\n' % k)
       
  1181         ui.write(' source   %s\n' % v[0])
       
  1182         ui.write(' revision %s\n' % v[1])
       
  1183 
       
  1184 def debugdag(ui, repo, file_=None, *revs, **opts):
       
  1185     """format the changelog or an index DAG as a concise textual description
       
  1186 
       
  1187     If you pass a revlog index, the revlog's DAG is emitted. If you list
       
  1188     revision numbers, they get labelled in the output as rN.
       
  1189 
       
  1190     Otherwise, the changelog DAG of the current repo is emitted.
       
  1191     """
       
  1192     spaces = opts.get('spaces')
       
  1193     dots = opts.get('dots')
       
  1194     if file_:
       
  1195         rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
       
  1196         revs = set((int(r) for r in revs))
       
  1197         def events():
       
  1198             for r in rlog:
       
  1199                 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
       
  1200                 if r in revs:
       
  1201                     yield 'l', (r, "r%i" % r)
       
  1202     elif repo:
       
  1203         cl = repo.changelog
       
  1204         tags = opts.get('tags')
       
  1205         branches = opts.get('branches')
       
  1206         if tags:
       
  1207             labels = {}
       
  1208             for l, n in repo.tags().items():
       
  1209                 labels.setdefault(cl.rev(n), []).append(l)
       
  1210         def events():
       
  1211             b = "default"
       
  1212             for r in cl:
       
  1213                 if branches:
       
  1214                     newb = cl.read(cl.node(r))[5]['branch']
       
  1215                     if newb != b:
       
  1216                         yield 'a', newb
       
  1217                         b = newb
       
  1218                 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
       
  1219                 if tags:
       
  1220                     ls = labels.get(r)
       
  1221                     if ls:
       
  1222                         for l in ls:
       
  1223                             yield 'l', (r, l)
       
  1224     else:
       
  1225         raise util.Abort(_('need repo for changelog dag'))
       
  1226 
       
  1227     for line in dagparser.dagtextlines(events(),
       
  1228                                        addspaces=spaces,
       
  1229                                        wraplabels=True,
       
  1230                                        wrapannotations=True,
       
  1231                                        wrapnonlinear=dots,
       
  1232                                        usedots=dots,
       
  1233                                        maxlinewidth=70):
       
  1234         ui.write(line)
       
  1235         ui.write("\n")
       
  1236 
       
  1237 def debugdata(ui, repo, file_, rev):
       
  1238     """dump the contents of a data file revision"""
       
  1239     r = None
       
  1240     if repo:
       
  1241         filelog = repo.file(file_)
       
  1242         if len(filelog):
       
  1243             r = filelog
       
  1244     if not r:
       
  1245         r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
       
  1246     try:
       
  1247         ui.write(r.revision(r.lookup(rev)))
       
  1248     except KeyError:
       
  1249         raise util.Abort(_('invalid revision identifier %s') % rev)
       
  1250 
       
  1251 def debugdate(ui, date, range=None, **opts):
       
  1252     """parse and display a date"""
       
  1253     if opts["extended"]:
       
  1254         d = util.parsedate(date, util.extendeddateformats)
       
  1255     else:
       
  1256         d = util.parsedate(date)
       
  1257     ui.write("internal: %s %s\n" % d)
       
  1258     ui.write("standard: %s\n" % util.datestr(d))
       
  1259     if range:
       
  1260         m = util.matchdate(range)
       
  1261         ui.write("match: %s\n" % m(d[0]))
       
  1262 
       
  1263 def debugindex(ui, repo, file_, **opts):
       
  1264     """dump the contents of an index file"""
       
  1265     r = None
       
  1266     if repo:
       
  1267         filelog = repo.file(file_)
       
  1268         if len(filelog):
       
  1269             r = filelog
       
  1270 
       
  1271     format = opts.get('format', 0)
       
  1272     if format not in (0, 1):
       
  1273         raise util.Abort("unknown format %d" % format)
       
  1274 
       
  1275     if not r:
       
  1276         r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
       
  1277 
       
  1278     if format == 0:
       
  1279         ui.write("   rev    offset  length   base linkrev"
       
  1280                  " nodeid       p1           p2\n")
       
  1281     elif format == 1:
       
  1282         ui.write("   rev flag   offset   length"
       
  1283                  "     size   base   link     p1     p2       nodeid\n")
       
  1284 
       
  1285     for i in r:
       
  1286         node = r.node(i)
       
  1287         if format == 0:
       
  1288             try:
       
  1289                 pp = r.parents(node)
       
  1290             except:
       
  1291                 pp = [nullid, nullid]
       
  1292             ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
       
  1293                     i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
       
  1294                     short(node), short(pp[0]), short(pp[1])))
       
  1295         elif format == 1:
       
  1296             pr = r.parentrevs(i)
       
  1297             ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
       
  1298                     i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
       
  1299                     r.base(i), r.linkrev(i), pr[0], pr[1], short(node)))
       
  1300 
       
  1301 def debugindexdot(ui, repo, file_):
       
  1302     """dump an index DAG as a graphviz dot file"""
       
  1303     r = None
       
  1304     if repo:
       
  1305         filelog = repo.file(file_)
       
  1306         if len(filelog):
       
  1307             r = filelog
       
  1308     if not r:
       
  1309         r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
       
  1310     ui.write("digraph G {\n")
       
  1311     for i in r:
       
  1312         node = r.node(i)
       
  1313         pp = r.parents(node)
       
  1314         ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
       
  1315         if pp[1] != nullid:
       
  1316             ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
       
  1317     ui.write("}\n")
       
  1318 
       
  1319 def debuginstall(ui):
       
  1320     '''test Mercurial installation
       
  1321 
       
  1322     Returns 0 on success.
       
  1323     '''
       
  1324 
       
  1325     def writetemp(contents):
       
  1326         (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
       
  1327         f = os.fdopen(fd, "wb")
       
  1328         f.write(contents)
       
  1329         f.close()
       
  1330         return name
       
  1331 
       
  1332     problems = 0
       
  1333 
       
  1334     # encoding
       
  1335     ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
       
  1336     try:
       
  1337         encoding.fromlocal("test")
       
  1338     except util.Abort, inst:
       
  1339         ui.write(" %s\n" % inst)
       
  1340         ui.write(_(" (check that your locale is properly set)\n"))
       
  1341         problems += 1
       
  1342 
       
  1343     # compiled modules
       
  1344     ui.status(_("Checking installed modules (%s)...\n")
       
  1345               % os.path.dirname(__file__))
       
  1346     try:
       
  1347         import bdiff, mpatch, base85, osutil
       
  1348     except Exception, inst:
       
  1349         ui.write(" %s\n" % inst)
       
  1350         ui.write(_(" One or more extensions could not be found"))
       
  1351         ui.write(_(" (check that you compiled the extensions)\n"))
       
  1352         problems += 1
       
  1353 
       
  1354     # templates
       
  1355     ui.status(_("Checking templates...\n"))
       
  1356     try:
       
  1357         import templater
       
  1358         templater.templater(templater.templatepath("map-cmdline.default"))
       
  1359     except Exception, inst:
       
  1360         ui.write(" %s\n" % inst)
       
  1361         ui.write(_(" (templates seem to have been installed incorrectly)\n"))
       
  1362         problems += 1
       
  1363 
       
  1364     # patch
       
  1365     ui.status(_("Checking patch...\n"))
       
  1366     patchproblems = 0
       
  1367     a = "1\n2\n3\n4\n"
       
  1368     b = "1\n2\n3\ninsert\n4\n"
       
  1369     fa = writetemp(a)
       
  1370     d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
       
  1371         os.path.basename(fa))
       
  1372     fd = writetemp(d)
       
  1373 
       
  1374     files = {}
       
  1375     try:
       
  1376         patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
       
  1377     except util.Abort, e:
       
  1378         ui.write(_(" patch call failed:\n"))
       
  1379         ui.write(" " + str(e) + "\n")
       
  1380         patchproblems += 1
       
  1381     else:
       
  1382         if list(files) != [os.path.basename(fa)]:
       
  1383             ui.write(_(" unexpected patch output!\n"))
       
  1384             patchproblems += 1
       
  1385         a = open(fa).read()
       
  1386         if a != b:
       
  1387             ui.write(_(" patch test failed!\n"))
       
  1388             patchproblems += 1
       
  1389 
       
  1390     if patchproblems:
       
  1391         if ui.config('ui', 'patch'):
       
  1392             ui.write(_(" (Current patch tool may be incompatible with patch,"
       
  1393                        " or misconfigured. Please check your configuration"
       
  1394                        " file)\n"))
       
  1395         else:
       
  1396             ui.write(_(" Internal patcher failure, please report this error"
       
  1397                        " to http://mercurial.selenic.com/wiki/BugTracker\n"))
       
  1398     problems += patchproblems
       
  1399 
       
  1400     os.unlink(fa)
       
  1401     os.unlink(fd)
       
  1402 
       
  1403     # editor
       
  1404     ui.status(_("Checking commit editor...\n"))
       
  1405     editor = ui.geteditor()
       
  1406     cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
       
  1407     if not cmdpath:
       
  1408         if editor == 'vi':
       
  1409             ui.write(_(" No commit editor set and can't find vi in PATH\n"))
       
  1410             ui.write(_(" (specify a commit editor in your configuration"
       
  1411                        " file)\n"))
       
  1412         else:
       
  1413             ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
       
  1414             ui.write(_(" (specify a commit editor in your configuration"
       
  1415                        " file)\n"))
       
  1416             problems += 1
       
  1417 
       
  1418     # check username
       
  1419     ui.status(_("Checking username...\n"))
       
  1420     try:
       
  1421         ui.username()
       
  1422     except util.Abort, e:
       
  1423         ui.write(" %s\n" % e)
       
  1424         ui.write(_(" (specify a username in your configuration file)\n"))
       
  1425         problems += 1
       
  1426 
       
  1427     if not problems:
       
  1428         ui.status(_("No problems detected\n"))
       
  1429     else:
       
  1430         ui.write(_("%s problems detected,"
       
  1431                    " please check your install!\n") % problems)
       
  1432 
       
  1433     return problems
       
  1434 
       
  1435 def debugrename(ui, repo, file1, *pats, **opts):
       
  1436     """dump rename information"""
       
  1437 
       
  1438     ctx = repo[opts.get('rev')]
       
  1439     m = cmdutil.match(repo, (file1,) + pats, opts)
       
  1440     for abs in ctx.walk(m):
       
  1441         fctx = ctx[abs]
       
  1442         o = fctx.filelog().renamed(fctx.filenode())
       
  1443         rel = m.rel(abs)
       
  1444         if o:
       
  1445             ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
       
  1446         else:
       
  1447             ui.write(_("%s not renamed\n") % rel)
       
  1448 
       
  1449 def debugwalk(ui, repo, *pats, **opts):
       
  1450     """show how files match on given patterns"""
       
  1451     m = cmdutil.match(repo, pats, opts)
       
  1452     items = list(repo.walk(m))
       
  1453     if not items:
       
  1454         return
       
  1455     fmt = 'f  %%-%ds  %%-%ds  %%s' % (
       
  1456         max([len(abs) for abs in items]),
       
  1457         max([len(m.rel(abs)) for abs in items]))
       
  1458     for abs in items:
       
  1459         line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
       
  1460         ui.write("%s\n" % line.rstrip())
       
  1461 
       
  1462 def diff(ui, repo, *pats, **opts):
       
  1463     """diff repository (or selected files)
       
  1464 
       
  1465     Show differences between revisions for the specified files.
       
  1466 
       
  1467     Differences between files are shown using the unified diff format.
       
  1468 
       
  1469     .. note::
       
  1470        diff may generate unexpected results for merges, as it will
       
  1471        default to comparing against the working directory's first
       
  1472        parent changeset if no revisions are specified.
       
  1473 
       
  1474     When two revision arguments are given, then changes are shown
       
  1475     between those revisions. If only one revision is specified then
       
  1476     that revision is compared to the working directory, and, when no
       
  1477     revisions are specified, the working directory files are compared
       
  1478     to its parent.
       
  1479 
       
  1480     Alternatively you can specify -c/--change with a revision to see
       
  1481     the changes in that changeset relative to its first parent.
       
  1482 
       
  1483     Without the -a/--text option, diff will avoid generating diffs of
       
  1484     files it detects as binary. With -a, diff will generate a diff
       
  1485     anyway, probably with undesirable results.
       
  1486 
       
  1487     Use the -g/--git option to generate diffs in the git extended diff
       
  1488     format. For more information, read :hg:`help diffs`.
       
  1489 
       
  1490     Returns 0 on success.
       
  1491     """
       
  1492 
       
  1493     revs = opts.get('rev')
       
  1494     change = opts.get('change')
       
  1495     stat = opts.get('stat')
       
  1496     reverse = opts.get('reverse')
       
  1497 
       
  1498     if revs and change:
       
  1499         msg = _('cannot specify --rev and --change at the same time')
       
  1500         raise util.Abort(msg)
       
  1501     elif change:
       
  1502         node2 = repo.lookup(change)
       
  1503         node1 = repo[node2].parents()[0].node()
       
  1504     else:
       
  1505         node1, node2 = cmdutil.revpair(repo, revs)
       
  1506 
       
  1507     if reverse:
       
  1508         node1, node2 = node2, node1
       
  1509 
       
  1510     diffopts = patch.diffopts(ui, opts)
       
  1511     m = cmdutil.match(repo, pats, opts)
       
  1512     cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
       
  1513                            listsubrepos=opts.get('subrepos'))
       
  1514 
       
  1515 def export(ui, repo, *changesets, **opts):
       
  1516     """dump the header and diffs for one or more changesets
       
  1517 
       
  1518     Print the changeset header and diffs for one or more revisions.
       
  1519 
       
  1520     The information shown in the changeset header is: author, date,
       
  1521     branch name (if non-default), changeset hash, parent(s) and commit
       
  1522     comment.
       
  1523 
       
  1524     .. note::
       
  1525        export may generate unexpected diff output for merge
       
  1526        changesets, as it will compare the merge changeset against its
       
  1527        first parent only.
       
  1528 
       
  1529     Output may be to a file, in which case the name of the file is
       
  1530     given using a format string. The formatting rules are as follows:
       
  1531 
       
  1532     :``%%``: literal "%" character
       
  1533     :``%H``: changeset hash (40 hexadecimal digits)
       
  1534     :``%N``: number of patches being generated
       
  1535     :``%R``: changeset revision number
       
  1536     :``%b``: basename of the exporting repository
       
  1537     :``%h``: short-form changeset hash (12 hexadecimal digits)
       
  1538     :``%n``: zero-padded sequence number, starting at 1
       
  1539     :``%r``: zero-padded changeset revision number
       
  1540 
       
  1541     Without the -a/--text option, export will avoid generating diffs
       
  1542     of files it detects as binary. With -a, export will generate a
       
  1543     diff anyway, probably with undesirable results.
       
  1544 
       
  1545     Use the -g/--git option to generate diffs in the git extended diff
       
  1546     format. See :hg:`help diffs` for more information.
       
  1547 
       
  1548     With the --switch-parent option, the diff will be against the
       
  1549     second parent. It can be useful to review a merge.
       
  1550 
       
  1551     Returns 0 on success.
       
  1552     """
       
  1553     changesets += tuple(opts.get('rev', []))
       
  1554     if not changesets:
       
  1555         raise util.Abort(_("export requires at least one changeset"))
       
  1556     revs = cmdutil.revrange(repo, changesets)
       
  1557     if len(revs) > 1:
       
  1558         ui.note(_('exporting patches:\n'))
       
  1559     else:
       
  1560         ui.note(_('exporting patch:\n'))
       
  1561     cmdutil.export(repo, revs, template=opts.get('output'),
       
  1562                  switch_parent=opts.get('switch_parent'),
       
  1563                  opts=patch.diffopts(ui, opts))
       
  1564 
       
  1565 def forget(ui, repo, *pats, **opts):
       
  1566     """forget the specified files on the next commit
       
  1567 
       
  1568     Mark the specified files so they will no longer be tracked
       
  1569     after the next commit.
       
  1570 
       
  1571     This only removes files from the current branch, not from the
       
  1572     entire project history, and it does not delete them from the
       
  1573     working directory.
       
  1574 
       
  1575     To undo a forget before the next commit, see :hg:`add`.
       
  1576 
       
  1577     Returns 0 on success.
       
  1578     """
       
  1579 
       
  1580     if not pats:
       
  1581         raise util.Abort(_('no files specified'))
       
  1582 
       
  1583     m = cmdutil.match(repo, pats, opts)
       
  1584     s = repo.status(match=m, clean=True)
       
  1585     forget = sorted(s[0] + s[1] + s[3] + s[6])
       
  1586     errs = 0
       
  1587 
       
  1588     for f in m.files():
       
  1589         if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
       
  1590             ui.warn(_('not removing %s: file is already untracked\n')
       
  1591                     % m.rel(f))
       
  1592             errs = 1
       
  1593 
       
  1594     for f in forget:
       
  1595         if ui.verbose or not m.exact(f):
       
  1596             ui.status(_('removing %s\n') % m.rel(f))
       
  1597 
       
  1598     repo[None].remove(forget, unlink=False)
       
  1599     return errs
       
  1600 
       
  1601 def grep(ui, repo, pattern, *pats, **opts):
       
  1602     """search for a pattern in specified files and revisions
       
  1603 
       
  1604     Search revisions of files for a regular expression.
       
  1605 
       
  1606     This command behaves differently than Unix grep. It only accepts
       
  1607     Python/Perl regexps. It searches repository history, not the
       
  1608     working directory. It always prints the revision number in which a
       
  1609     match appears.
       
  1610 
       
  1611     By default, grep only prints output for the first revision of a
       
  1612     file in which it finds a match. To get it to print every revision
       
  1613     that contains a change in match status ("-" for a match that
       
  1614     becomes a non-match, or "+" for a non-match that becomes a match),
       
  1615     use the --all flag.
       
  1616 
       
  1617     Returns 0 if a match is found, 1 otherwise.
       
  1618     """
       
  1619     reflags = 0
       
  1620     if opts.get('ignore_case'):
       
  1621         reflags |= re.I
       
  1622     try:
       
  1623         regexp = re.compile(pattern, reflags)
       
  1624     except re.error, inst:
       
  1625         ui.warn(_("grep: invalid match pattern: %s\n") % inst)
       
  1626         return 1
       
  1627     sep, eol = ':', '\n'
       
  1628     if opts.get('print0'):
       
  1629         sep = eol = '\0'
       
  1630 
       
  1631     getfile = util.lrucachefunc(repo.file)
       
  1632 
       
  1633     def matchlines(body):
       
  1634         begin = 0
       
  1635         linenum = 0
       
  1636         while True:
       
  1637             match = regexp.search(body, begin)
       
  1638             if not match:
       
  1639                 break
       
  1640             mstart, mend = match.span()
       
  1641             linenum += body.count('\n', begin, mstart) + 1
       
  1642             lstart = body.rfind('\n', begin, mstart) + 1 or begin
       
  1643             begin = body.find('\n', mend) + 1 or len(body)
       
  1644             lend = begin - 1
       
  1645             yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
       
  1646 
       
  1647     class linestate(object):
       
  1648         def __init__(self, line, linenum, colstart, colend):
       
  1649             self.line = line
       
  1650             self.linenum = linenum
       
  1651             self.colstart = colstart
       
  1652             self.colend = colend
       
  1653 
       
  1654         def __hash__(self):
       
  1655             return hash((self.linenum, self.line))
       
  1656 
       
  1657         def __eq__(self, other):
       
  1658             return self.line == other.line
       
  1659 
       
  1660     matches = {}
       
  1661     copies = {}
       
  1662     def grepbody(fn, rev, body):
       
  1663         matches[rev].setdefault(fn, [])
       
  1664         m = matches[rev][fn]
       
  1665         for lnum, cstart, cend, line in matchlines(body):
       
  1666             s = linestate(line, lnum, cstart, cend)
       
  1667             m.append(s)
       
  1668 
       
  1669     def difflinestates(a, b):
       
  1670         sm = difflib.SequenceMatcher(None, a, b)
       
  1671         for tag, alo, ahi, blo, bhi in sm.get_opcodes():
       
  1672             if tag == 'insert':
       
  1673                 for i in xrange(blo, bhi):
       
  1674                     yield ('+', b[i])
       
  1675             elif tag == 'delete':
       
  1676                 for i in xrange(alo, ahi):
       
  1677                     yield ('-', a[i])
       
  1678             elif tag == 'replace':
       
  1679                 for i in xrange(alo, ahi):
       
  1680                     yield ('-', a[i])
       
  1681                 for i in xrange(blo, bhi):
       
  1682                     yield ('+', b[i])
       
  1683 
       
  1684     def display(fn, ctx, pstates, states):
       
  1685         rev = ctx.rev()
       
  1686         datefunc = ui.quiet and util.shortdate or util.datestr
       
  1687         found = False
       
  1688         filerevmatches = {}
       
  1689         if opts.get('all'):
       
  1690             iter = difflinestates(pstates, states)
       
  1691         else:
       
  1692             iter = [('', l) for l in states]
       
  1693         for change, l in iter:
       
  1694             cols = [fn, str(rev)]
       
  1695             before, match, after = None, None, None
       
  1696             if opts.get('line_number'):
       
  1697                 cols.append(str(l.linenum))
       
  1698             if opts.get('all'):
       
  1699                 cols.append(change)
       
  1700             if opts.get('user'):
       
  1701                 cols.append(ui.shortuser(ctx.user()))
       
  1702             if opts.get('date'):
       
  1703                 cols.append(datefunc(ctx.date()))
       
  1704             if opts.get('files_with_matches'):
       
  1705                 c = (fn, rev)
       
  1706                 if c in filerevmatches:
       
  1707                     continue
       
  1708                 filerevmatches[c] = 1
       
  1709             else:
       
  1710                 before = l.line[:l.colstart]
       
  1711                 match = l.line[l.colstart:l.colend]
       
  1712                 after = l.line[l.colend:]
       
  1713             ui.write(sep.join(cols))
       
  1714             if before is not None:
       
  1715                 ui.write(sep + before)
       
  1716                 ui.write(match, label='grep.match')
       
  1717                 ui.write(after)
       
  1718             ui.write(eol)
       
  1719             found = True
       
  1720         return found
       
  1721 
       
  1722     skip = {}
       
  1723     revfiles = {}
       
  1724     matchfn = cmdutil.match(repo, pats, opts)
       
  1725     found = False
       
  1726     follow = opts.get('follow')
       
  1727 
       
  1728     def prep(ctx, fns):
       
  1729         rev = ctx.rev()
       
  1730         pctx = ctx.parents()[0]
       
  1731         parent = pctx.rev()
       
  1732         matches.setdefault(rev, {})
       
  1733         matches.setdefault(parent, {})
       
  1734         files = revfiles.setdefault(rev, [])
       
  1735         for fn in fns:
       
  1736             flog = getfile(fn)
       
  1737             try:
       
  1738                 fnode = ctx.filenode(fn)
       
  1739             except error.LookupError:
       
  1740                 continue
       
  1741 
       
  1742             copied = flog.renamed(fnode)
       
  1743             copy = follow and copied and copied[0]
       
  1744             if copy:
       
  1745                 copies.setdefault(rev, {})[fn] = copy
       
  1746             if fn in skip:
       
  1747                 if copy:
       
  1748                     skip[copy] = True
       
  1749                 continue
       
  1750             files.append(fn)
       
  1751 
       
  1752             if fn not in matches[rev]:
       
  1753                 grepbody(fn, rev, flog.read(fnode))
       
  1754 
       
  1755             pfn = copy or fn
       
  1756             if pfn not in matches[parent]:
       
  1757                 try:
       
  1758                     fnode = pctx.filenode(pfn)
       
  1759                     grepbody(pfn, parent, flog.read(fnode))
       
  1760                 except error.LookupError:
       
  1761                     pass
       
  1762 
       
  1763     for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
       
  1764         rev = ctx.rev()
       
  1765         parent = ctx.parents()[0].rev()
       
  1766         for fn in sorted(revfiles.get(rev, [])):
       
  1767             states = matches[rev][fn]
       
  1768             copy = copies.get(rev, {}).get(fn)
       
  1769             if fn in skip:
       
  1770                 if copy:
       
  1771                     skip[copy] = True
       
  1772                 continue
       
  1773             pstates = matches.get(parent, {}).get(copy or fn, [])
       
  1774             if pstates or states:
       
  1775                 r = display(fn, ctx, pstates, states)
       
  1776                 found = found or r
       
  1777                 if r and not opts.get('all'):
       
  1778                     skip[fn] = True
       
  1779                     if copy:
       
  1780                         skip[copy] = True
       
  1781         del matches[rev]
       
  1782         del revfiles[rev]
       
  1783 
       
  1784     return not found
       
  1785 
       
  1786 def heads(ui, repo, *branchrevs, **opts):
       
  1787     """show current repository heads or show branch heads
       
  1788 
       
  1789     With no arguments, show all repository branch heads.
       
  1790 
       
  1791     Repository "heads" are changesets with no child changesets. They are
       
  1792     where development generally takes place and are the usual targets
       
  1793     for update and merge operations. Branch heads are changesets that have
       
  1794     no child changeset on the same branch.
       
  1795 
       
  1796     If one or more REVs are given, only branch heads on the branches
       
  1797     associated with the specified changesets are shown.
       
  1798 
       
  1799     If -c/--closed is specified, also show branch heads marked closed
       
  1800     (see :hg:`commit --close-branch`).
       
  1801 
       
  1802     If STARTREV is specified, only those heads that are descendants of
       
  1803     STARTREV will be displayed.
       
  1804 
       
  1805     If -t/--topo is specified, named branch mechanics will be ignored and only
       
  1806     changesets without children will be shown.
       
  1807 
       
  1808     Returns 0 if matching heads are found, 1 if not.
       
  1809     """
       
  1810 
       
  1811     if opts.get('rev'):
       
  1812         start = repo.lookup(opts['rev'])
       
  1813     else:
       
  1814         start = None
       
  1815 
       
  1816     if opts.get('topo'):
       
  1817         heads = [repo[h] for h in repo.heads(start)]
       
  1818     else:
       
  1819         heads = []
       
  1820         for b, ls in repo.branchmap().iteritems():
       
  1821             if start is None:
       
  1822                 heads += [repo[h] for h in ls]
       
  1823                 continue
       
  1824             startrev = repo.changelog.rev(start)
       
  1825             descendants = set(repo.changelog.descendants(startrev))
       
  1826             descendants.add(startrev)
       
  1827             rev = repo.changelog.rev
       
  1828             heads += [repo[h] for h in ls if rev(h) in descendants]
       
  1829 
       
  1830     if branchrevs:
       
  1831         decode, encode = encoding.fromlocal, encoding.tolocal
       
  1832         branches = set(repo[decode(br)].branch() for br in branchrevs)
       
  1833         heads = [h for h in heads if h.branch() in branches]
       
  1834 
       
  1835     if not opts.get('closed'):
       
  1836         heads = [h for h in heads if not h.extra().get('close')]
       
  1837 
       
  1838     if opts.get('active') and branchrevs:
       
  1839         dagheads = repo.heads(start)
       
  1840         heads = [h for h in heads if h.node() in dagheads]
       
  1841 
       
  1842     if branchrevs:
       
  1843         haveheads = set(h.branch() for h in heads)
       
  1844         if branches - haveheads:
       
  1845             headless = ', '.join(encode(b) for b in branches - haveheads)
       
  1846             msg = _('no open branch heads found on branches %s')
       
  1847             if opts.get('rev'):
       
  1848                 msg += _(' (started at %s)' % opts['rev'])
       
  1849             ui.warn((msg + '\n') % headless)
       
  1850 
       
  1851     if not heads:
       
  1852         return 1
       
  1853 
       
  1854     heads = sorted(heads, key=lambda x: -x.rev())
       
  1855     displayer = cmdutil.show_changeset(ui, repo, opts)
       
  1856     for ctx in heads:
       
  1857         displayer.show(ctx)
       
  1858     displayer.close()
       
  1859 
       
  1860 def help_(ui, name=None, with_version=False, unknowncmd=False):
       
  1861     """show help for a given topic or a help overview
       
  1862 
       
  1863     With no arguments, print a list of commands with short help messages.
       
  1864 
       
  1865     Given a topic, extension, or command name, print help for that
       
  1866     topic.
       
  1867 
       
  1868     Returns 0 if successful.
       
  1869     """
       
  1870     option_lists = []
       
  1871     textwidth = ui.termwidth() - 2
       
  1872 
       
  1873     def addglobalopts(aliases):
       
  1874         if ui.verbose:
       
  1875             option_lists.append((_("global options:"), globalopts))
       
  1876             if name == 'shortlist':
       
  1877                 option_lists.append((_('use "hg help" for the full list '
       
  1878                                        'of commands'), ()))
       
  1879         else:
       
  1880             if name == 'shortlist':
       
  1881                 msg = _('use "hg help" for the full list of commands '
       
  1882                         'or "hg -v" for details')
       
  1883             elif aliases:
       
  1884                 msg = _('use "hg -v help%s" to show aliases and '
       
  1885                         'global options') % (name and " " + name or "")
       
  1886             else:
       
  1887                 msg = _('use "hg -v help %s" to show global options') % name
       
  1888             option_lists.append((msg, ()))
       
  1889 
       
  1890     def helpcmd(name):
       
  1891         if with_version:
       
  1892             version_(ui)
       
  1893             ui.write('\n')
       
  1894 
       
  1895         try:
       
  1896             aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
       
  1897         except error.AmbiguousCommand, inst:
       
  1898             # py3k fix: except vars can't be used outside the scope of the
       
  1899             # except block, nor can be used inside a lambda. python issue4617
       
  1900             prefix = inst.args[0]
       
  1901             select = lambda c: c.lstrip('^').startswith(prefix)
       
  1902             helplist(_('list of commands:\n\n'), select)
       
  1903             return
       
  1904 
       
  1905         # check if it's an invalid alias and display its error if it is
       
  1906         if getattr(entry[0], 'badalias', False):
       
  1907             if not unknowncmd:
       
  1908                 entry[0](ui)
       
  1909             return
       
  1910 
       
  1911         # synopsis
       
  1912         if len(entry) > 2:
       
  1913             if entry[2].startswith('hg'):
       
  1914                 ui.write("%s\n" % entry[2])
       
  1915             else:
       
  1916                 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
       
  1917         else:
       
  1918             ui.write('hg %s\n' % aliases[0])
       
  1919 
       
  1920         # aliases
       
  1921         if not ui.quiet and len(aliases) > 1:
       
  1922             ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
       
  1923 
       
  1924         # description
       
  1925         doc = gettext(entry[0].__doc__)
       
  1926         if not doc:
       
  1927             doc = _("(no help text available)")
       
  1928         if hasattr(entry[0], 'definition'):  # aliased command
       
  1929             if entry[0].definition.startswith('!'):  # shell alias
       
  1930                 doc = _('shell alias for::\n\n    %s') % entry[0].definition[1:]
       
  1931             else:
       
  1932                 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
       
  1933         if ui.quiet:
       
  1934             doc = doc.splitlines()[0]
       
  1935         keep = ui.verbose and ['verbose'] or []
       
  1936         formatted, pruned = minirst.format(doc, textwidth, keep=keep)
       
  1937         ui.write("\n%s\n" % formatted)
       
  1938         if pruned:
       
  1939             ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
       
  1940 
       
  1941         if not ui.quiet:
       
  1942             # options
       
  1943             if entry[1]:
       
  1944                 option_lists.append((_("options:\n"), entry[1]))
       
  1945 
       
  1946             addglobalopts(False)
       
  1947 
       
  1948     def helplist(header, select=None):
       
  1949         h = {}
       
  1950         cmds = {}
       
  1951         for c, e in table.iteritems():
       
  1952             f = c.split("|", 1)[0]
       
  1953             if select and not select(f):
       
  1954                 continue
       
  1955             if (not select and name != 'shortlist' and
       
  1956                 e[0].__module__ != __name__):
       
  1957                 continue
       
  1958             if name == "shortlist" and not f.startswith("^"):
       
  1959                 continue
       
  1960             f = f.lstrip("^")
       
  1961             if not ui.debugflag and f.startswith("debug"):
       
  1962                 continue
       
  1963             doc = e[0].__doc__
       
  1964             if doc and 'DEPRECATED' in doc and not ui.verbose:
       
  1965                 continue
       
  1966             doc = gettext(doc)
       
  1967             if not doc:
       
  1968                 doc = _("(no help text available)")
       
  1969             h[f] = doc.splitlines()[0].rstrip()
       
  1970             cmds[f] = c.lstrip("^")
       
  1971 
       
  1972         if not h:
       
  1973             ui.status(_('no commands defined\n'))
       
  1974             return
       
  1975 
       
  1976         ui.status(header)
       
  1977         fns = sorted(h)
       
  1978         m = max(map(len, fns))
       
  1979         for f in fns:
       
  1980             if ui.verbose:
       
  1981                 commands = cmds[f].replace("|",", ")
       
  1982                 ui.write(" %s:\n      %s\n"%(commands, h[f]))
       
  1983             else:
       
  1984                 ui.write('%s\n' % (util.wrap(h[f], textwidth,
       
  1985                                              initindent=' %-*s   ' % (m, f),
       
  1986                                              hangindent=' ' * (m + 4))))
       
  1987 
       
  1988         if not ui.quiet:
       
  1989             addglobalopts(True)
       
  1990 
       
  1991     def helptopic(name):
       
  1992         for names, header, doc in help.helptable:
       
  1993             if name in names:
       
  1994                 break
       
  1995         else:
       
  1996             raise error.UnknownCommand(name)
       
  1997 
       
  1998         # description
       
  1999         if not doc:
       
  2000             doc = _("(no help text available)")
       
  2001         if hasattr(doc, '__call__'):
       
  2002             doc = doc()
       
  2003 
       
  2004         ui.write("%s\n\n" % header)
       
  2005         ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
       
  2006 
       
  2007     def helpext(name):
       
  2008         try:
       
  2009             mod = extensions.find(name)
       
  2010             doc = gettext(mod.__doc__) or _('no help text available')
       
  2011         except KeyError:
       
  2012             mod = None
       
  2013             doc = extensions.disabledext(name)
       
  2014             if not doc:
       
  2015                 raise error.UnknownCommand(name)
       
  2016 
       
  2017         if '\n' not in doc:
       
  2018             head, tail = doc, ""
       
  2019         else:
       
  2020             head, tail = doc.split('\n', 1)
       
  2021         ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
       
  2022         if tail:
       
  2023             ui.write(minirst.format(tail, textwidth))
       
  2024             ui.status('\n\n')
       
  2025 
       
  2026         if mod:
       
  2027             try:
       
  2028                 ct = mod.cmdtable
       
  2029             except AttributeError:
       
  2030                 ct = {}
       
  2031             modcmds = set([c.split('|', 1)[0] for c in ct])
       
  2032             helplist(_('list of commands:\n\n'), modcmds.__contains__)
       
  2033         else:
       
  2034             ui.write(_('use "hg help extensions" for information on enabling '
       
  2035                        'extensions\n'))
       
  2036 
       
  2037     def helpextcmd(name):
       
  2038         cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
       
  2039         doc = gettext(mod.__doc__).splitlines()[0]
       
  2040 
       
  2041         msg = help.listexts(_("'%s' is provided by the following "
       
  2042                               "extension:") % cmd, {ext: doc}, len(ext),
       
  2043                             indent=4)
       
  2044         ui.write(minirst.format(msg, textwidth))
       
  2045         ui.write('\n\n')
       
  2046         ui.write(_('use "hg help extensions" for information on enabling '
       
  2047                    'extensions\n'))
       
  2048 
       
  2049     help.addtopichook('revsets', revset.makedoc)
       
  2050 
       
  2051     if name and name != 'shortlist':
       
  2052         i = None
       
  2053         if unknowncmd:
       
  2054             queries = (helpextcmd,)
       
  2055         else:
       
  2056             queries = (helptopic, helpcmd, helpext, helpextcmd)
       
  2057         for f in queries:
       
  2058             try:
       
  2059                 f(name)
       
  2060                 i = None
       
  2061                 break
       
  2062             except error.UnknownCommand, inst:
       
  2063                 i = inst
       
  2064         if i:
       
  2065             raise i
       
  2066 
       
  2067     else:
       
  2068         # program name
       
  2069         if ui.verbose or with_version:
       
  2070             version_(ui)
       
  2071         else:
       
  2072             ui.status(_("Mercurial Distributed SCM\n"))
       
  2073         ui.status('\n')
       
  2074 
       
  2075         # list of commands
       
  2076         if name == "shortlist":
       
  2077             header = _('basic commands:\n\n')
       
  2078         else:
       
  2079             header = _('list of commands:\n\n')
       
  2080 
       
  2081         helplist(header)
       
  2082         if name != 'shortlist':
       
  2083             exts, maxlength = extensions.enabled()
       
  2084             text = help.listexts(_('enabled extensions:'), exts, maxlength)
       
  2085             if text:
       
  2086                 ui.write("\n%s\n" % minirst.format(text, textwidth))
       
  2087 
       
  2088     # list all option lists
       
  2089     opt_output = []
       
  2090     multioccur = False
       
  2091     for title, options in option_lists:
       
  2092         opt_output.append(("\n%s" % title, None))
       
  2093         for option in options:
       
  2094             if len(option) == 5:
       
  2095                 shortopt, longopt, default, desc, optlabel = option
       
  2096             else:
       
  2097                 shortopt, longopt, default, desc = option
       
  2098                 optlabel = _("VALUE") # default label
       
  2099 
       
  2100             if _("DEPRECATED") in desc and not ui.verbose:
       
  2101                 continue
       
  2102             if isinstance(default, list):
       
  2103                 numqualifier = " %s [+]" % optlabel
       
  2104                 multioccur = True
       
  2105             elif (default is not None) and not isinstance(default, bool):
       
  2106                 numqualifier = " %s" % optlabel
       
  2107             else:
       
  2108                 numqualifier = ""
       
  2109             opt_output.append(("%2s%s" %
       
  2110                                (shortopt and "-%s" % shortopt,
       
  2111                                 longopt and " --%s%s" %
       
  2112                                 (longopt, numqualifier)),
       
  2113                                "%s%s" % (desc,
       
  2114                                          default
       
  2115                                          and _(" (default: %s)") % default
       
  2116                                          or "")))
       
  2117     if multioccur:
       
  2118         msg = _("\n[+] marked option can be specified multiple times")
       
  2119         if ui.verbose and name != 'shortlist':
       
  2120             opt_output.append((msg, None))
       
  2121         else:
       
  2122             opt_output.insert(-1, (msg, None))
       
  2123 
       
  2124     if not name:
       
  2125         ui.write(_("\nadditional help topics:\n\n"))
       
  2126         topics = []
       
  2127         for names, header, doc in help.helptable:
       
  2128             topics.append((sorted(names, key=len, reverse=True)[0], header))
       
  2129         topics_len = max([len(s[0]) for s in topics])
       
  2130         for t, desc in topics:
       
  2131             ui.write(" %-*s  %s\n" % (topics_len, t, desc))
       
  2132 
       
  2133     if opt_output:
       
  2134         colwidth = encoding.colwidth
       
  2135         # normalize: (opt or message, desc or None, width of opt)
       
  2136         entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
       
  2137                    for opt, desc in opt_output]
       
  2138         hanging = max([e[2] for e in entries])
       
  2139         for opt, desc, width in entries:
       
  2140             if desc:
       
  2141                 initindent = ' %s%s  ' % (opt, ' ' * (hanging - width))
       
  2142                 hangindent = ' ' * (hanging + 3)
       
  2143                 ui.write('%s\n' % (util.wrap(desc, textwidth,
       
  2144                                              initindent=initindent,
       
  2145                                              hangindent=hangindent)))
       
  2146             else:
       
  2147                 ui.write("%s\n" % opt)
       
  2148 
       
  2149 def identify(ui, repo, source=None,
       
  2150              rev=None, num=None, id=None, branch=None, tags=None):
       
  2151     """identify the working copy or specified revision
       
  2152 
       
  2153     With no revision, print a summary of the current state of the
       
  2154     repository.
       
  2155 
       
  2156     Specifying a path to a repository root or Mercurial bundle will
       
  2157     cause lookup to operate on that repository/bundle.
       
  2158 
       
  2159     This summary identifies the repository state using one or two
       
  2160     parent hash identifiers, followed by a "+" if there are
       
  2161     uncommitted changes in the working directory, a list of tags for
       
  2162     this revision and a branch name for non-default branches.
       
  2163 
       
  2164     Returns 0 if successful.
       
  2165     """
       
  2166 
       
  2167     if not repo and not source:
       
  2168         raise util.Abort(_("there is no Mercurial repository here "
       
  2169                            "(.hg not found)"))
       
  2170 
       
  2171     hexfunc = ui.debugflag and hex or short
       
  2172     default = not (num or id or branch or tags)
       
  2173     output = []
       
  2174 
       
  2175     revs = []
       
  2176     if source:
       
  2177         source, branches = hg.parseurl(ui.expandpath(source))
       
  2178         repo = hg.repository(ui, source)
       
  2179         revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
       
  2180 
       
  2181     if not repo.local():
       
  2182         if not rev and revs:
       
  2183             rev = revs[0]
       
  2184         if not rev:
       
  2185             rev = "tip"
       
  2186         if num or branch or tags:
       
  2187             raise util.Abort(
       
  2188                 "can't query remote revision number, branch, or tags")
       
  2189         output = [hexfunc(repo.lookup(rev))]
       
  2190     elif not rev:
       
  2191         ctx = repo[None]
       
  2192         parents = ctx.parents()
       
  2193         changed = False
       
  2194         if default or id or num:
       
  2195             changed = util.any(repo.status())
       
  2196         if default or id:
       
  2197             output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
       
  2198                                 (changed) and "+" or "")]
       
  2199         if num:
       
  2200             output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
       
  2201                                     (changed) and "+" or ""))
       
  2202     else:
       
  2203         ctx = repo[rev]
       
  2204         if default or id:
       
  2205             output = [hexfunc(ctx.node())]
       
  2206         if num:
       
  2207             output.append(str(ctx.rev()))
       
  2208 
       
  2209     if repo.local() and default and not ui.quiet:
       
  2210         b = encoding.tolocal(ctx.branch())
       
  2211         if b != 'default':
       
  2212             output.append("(%s)" % b)
       
  2213 
       
  2214         # multiple tags for a single parent separated by '/'
       
  2215         t = "/".join(ctx.tags())
       
  2216         if t:
       
  2217             output.append(t)
       
  2218 
       
  2219     if branch:
       
  2220         output.append(encoding.tolocal(ctx.branch()))
       
  2221 
       
  2222     if tags:
       
  2223         output.extend(ctx.tags())
       
  2224 
       
  2225     ui.write("%s\n" % ' '.join(output))
       
  2226 
       
  2227 def import_(ui, repo, patch1, *patches, **opts):
       
  2228     """import an ordered set of patches
       
  2229 
       
  2230     Import a list of patches and commit them individually (unless
       
  2231     --no-commit is specified).
       
  2232 
       
  2233     If there are outstanding changes in the working directory, import
       
  2234     will abort unless given the -f/--force flag.
       
  2235 
       
  2236     You can import a patch straight from a mail message. Even patches
       
  2237     as attachments work (to use the body part, it must have type
       
  2238     text/plain or text/x-patch). From and Subject headers of email
       
  2239     message are used as default committer and commit message. All
       
  2240     text/plain body parts before first diff are added to commit
       
  2241     message.
       
  2242 
       
  2243     If the imported patch was generated by :hg:`export`, user and
       
  2244     description from patch override values from message headers and
       
  2245     body. Values given on command line with -m/--message and -u/--user
       
  2246     override these.
       
  2247 
       
  2248     If --exact is specified, import will set the working directory to
       
  2249     the parent of each patch before applying it, and will abort if the
       
  2250     resulting changeset has a different ID than the one recorded in
       
  2251     the patch. This may happen due to character set problems or other
       
  2252     deficiencies in the text patch format.
       
  2253 
       
  2254     With -s/--similarity, hg will attempt to discover renames and
       
  2255     copies in the patch in the same way as 'addremove'.
       
  2256 
       
  2257     To read a patch from standard input, use "-" as the patch name. If
       
  2258     a URL is specified, the patch will be downloaded from it.
       
  2259     See :hg:`help dates` for a list of formats valid for -d/--date.
       
  2260 
       
  2261     Returns 0 on success.
       
  2262     """
       
  2263     patches = (patch1,) + patches
       
  2264 
       
  2265     date = opts.get('date')
       
  2266     if date:
       
  2267         opts['date'] = util.parsedate(date)
       
  2268 
       
  2269     try:
       
  2270         sim = float(opts.get('similarity') or 0)
       
  2271     except ValueError:
       
  2272         raise util.Abort(_('similarity must be a number'))
       
  2273     if sim < 0 or sim > 100:
       
  2274         raise util.Abort(_('similarity must be between 0 and 100'))
       
  2275 
       
  2276     if opts.get('exact') or not opts.get('force'):
       
  2277         cmdutil.bail_if_changed(repo)
       
  2278 
       
  2279     d = opts["base"]
       
  2280     strip = opts["strip"]
       
  2281     wlock = lock = None
       
  2282 
       
  2283     def tryone(ui, hunk):
       
  2284         tmpname, message, user, date, branch, nodeid, p1, p2 = \
       
  2285             patch.extract(ui, hunk)
       
  2286 
       
  2287         if not tmpname:
       
  2288             return None
       
  2289         commitid = _('to working directory')
       
  2290 
       
  2291         try:
       
  2292             cmdline_message = cmdutil.logmessage(opts)
       
  2293             if cmdline_message:
       
  2294                 # pickup the cmdline msg
       
  2295                 message = cmdline_message
       
  2296             elif message:
       
  2297                 # pickup the patch msg
       
  2298                 message = message.strip()
       
  2299             else:
       
  2300                 # launch the editor
       
  2301                 message = None
       
  2302             ui.debug('message:\n%s\n' % message)
       
  2303 
       
  2304             wp = repo.parents()
       
  2305             if opts.get('exact'):
       
  2306                 if not nodeid or not p1:
       
  2307                     raise util.Abort(_('not a Mercurial patch'))
       
  2308                 p1 = repo.lookup(p1)
       
  2309                 p2 = repo.lookup(p2 or hex(nullid))
       
  2310 
       
  2311                 if p1 != wp[0].node():
       
  2312                     hg.clean(repo, p1)
       
  2313                 repo.dirstate.setparents(p1, p2)
       
  2314             elif p2:
       
  2315                 try:
       
  2316                     p1 = repo.lookup(p1)
       
  2317                     p2 = repo.lookup(p2)
       
  2318                     if p1 == wp[0].node():
       
  2319                         repo.dirstate.setparents(p1, p2)
       
  2320                 except error.RepoError:
       
  2321                     pass
       
  2322             if opts.get('exact') or opts.get('import_branch'):
       
  2323                 repo.dirstate.setbranch(branch or 'default')
       
  2324 
       
  2325             files = {}
       
  2326             try:
       
  2327                 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
       
  2328                             files=files, eolmode=None)
       
  2329             finally:
       
  2330                 files = cmdutil.updatedir(ui, repo, files,
       
  2331                                           similarity=sim / 100.0)
       
  2332             if not opts.get('no_commit'):
       
  2333                 if opts.get('exact'):
       
  2334                     m = None
       
  2335                 else:
       
  2336                     m = cmdutil.matchfiles(repo, files or [])
       
  2337                 n = repo.commit(message, opts.get('user') or user,
       
  2338                                 opts.get('date') or date, match=m,
       
  2339                                 editor=cmdutil.commiteditor)
       
  2340                 if opts.get('exact'):
       
  2341                     if hex(n) != nodeid:
       
  2342                         repo.rollback()
       
  2343                         raise util.Abort(_('patch is damaged'
       
  2344                                            ' or loses information'))
       
  2345                 # Force a dirstate write so that the next transaction
       
  2346                 # backups an up-do-date file.
       
  2347                 repo.dirstate.write()
       
  2348                 if n:
       
  2349                     commitid = short(n)
       
  2350 
       
  2351             return commitid
       
  2352         finally:
       
  2353             os.unlink(tmpname)
       
  2354 
       
  2355     try:
       
  2356         wlock = repo.wlock()
       
  2357         lock = repo.lock()
       
  2358         lastcommit = None
       
  2359         for p in patches:
       
  2360             pf = os.path.join(d, p)
       
  2361 
       
  2362             if pf == '-':
       
  2363                 ui.status(_("applying patch from stdin\n"))
       
  2364                 pf = sys.stdin
       
  2365             else:
       
  2366                 ui.status(_("applying %s\n") % p)
       
  2367                 pf = url.open(ui, pf)
       
  2368 
       
  2369             haspatch = False
       
  2370             for hunk in patch.split(pf):
       
  2371                 commitid = tryone(ui, hunk)
       
  2372                 if commitid:
       
  2373                     haspatch = True
       
  2374                     if lastcommit:
       
  2375                         ui.status(_('applied %s\n') % lastcommit)
       
  2376                     lastcommit = commitid
       
  2377 
       
  2378             if not haspatch:
       
  2379                 raise util.Abort(_('no diffs found'))
       
  2380 
       
  2381     finally:
       
  2382         release(lock, wlock)
       
  2383 
       
  2384 def incoming(ui, repo, source="default", **opts):
       
  2385     """show new changesets found in source
       
  2386 
       
  2387     Show new changesets found in the specified path/URL or the default
       
  2388     pull location. These are the changesets that would have been pulled
       
  2389     if a pull at the time you issued this command.
       
  2390 
       
  2391     For remote repository, using --bundle avoids downloading the
       
  2392     changesets twice if the incoming is followed by a pull.
       
  2393 
       
  2394     See pull for valid source format details.
       
  2395 
       
  2396     Returns 0 if there are incoming changes, 1 otherwise.
       
  2397     """
       
  2398     if opts.get('bundle') and opts.get('subrepos'):
       
  2399         raise util.Abort(_('cannot combine --bundle and --subrepos'))
       
  2400 
       
  2401     ret = hg.incoming(ui, repo, source, opts)
       
  2402     return ret
       
  2403 
       
  2404 def init(ui, dest=".", **opts):
       
  2405     """create a new repository in the given directory
       
  2406 
       
  2407     Initialize a new repository in the given directory. If the given
       
  2408     directory does not exist, it will be created.
       
  2409 
       
  2410     If no directory is given, the current directory is used.
       
  2411 
       
  2412     It is possible to specify an ``ssh://`` URL as the destination.
       
  2413     See :hg:`help urls` for more information.
       
  2414 
       
  2415     Returns 0 on success.
       
  2416     """
       
  2417     hg.repository(hg.remoteui(ui, opts), ui.expandpath(dest), create=1)
       
  2418 
       
  2419 def locate(ui, repo, *pats, **opts):
       
  2420     """locate files matching specific patterns
       
  2421 
       
  2422     Print files under Mercurial control in the working directory whose
       
  2423     names match the given patterns.
       
  2424 
       
  2425     By default, this command searches all directories in the working
       
  2426     directory. To search just the current directory and its
       
  2427     subdirectories, use "--include .".
       
  2428 
       
  2429     If no patterns are given to match, this command prints the names
       
  2430     of all files under Mercurial control in the working directory.
       
  2431 
       
  2432     If you want to feed the output of this command into the "xargs"
       
  2433     command, use the -0 option to both this command and "xargs". This
       
  2434     will avoid the problem of "xargs" treating single filenames that
       
  2435     contain whitespace as multiple filenames.
       
  2436 
       
  2437     Returns 0 if a match is found, 1 otherwise.
       
  2438     """
       
  2439     end = opts.get('print0') and '\0' or '\n'
       
  2440     rev = opts.get('rev') or None
       
  2441 
       
  2442     ret = 1
       
  2443     m = cmdutil.match(repo, pats, opts, default='relglob')
       
  2444     m.bad = lambda x, y: False
       
  2445     for abs in repo[rev].walk(m):
       
  2446         if not rev and abs not in repo.dirstate:
       
  2447             continue
       
  2448         if opts.get('fullpath'):
       
  2449             ui.write(repo.wjoin(abs), end)
       
  2450         else:
       
  2451             ui.write(((pats and m.rel(abs)) or abs), end)
       
  2452         ret = 0
       
  2453 
       
  2454     return ret
       
  2455 
       
  2456 def log(ui, repo, *pats, **opts):
       
  2457     """show revision history of entire repository or files
       
  2458 
       
  2459     Print the revision history of the specified files or the entire
       
  2460     project.
       
  2461 
       
  2462     File history is shown without following rename or copy history of
       
  2463     files. Use -f/--follow with a filename to follow history across
       
  2464     renames and copies. --follow without a filename will only show
       
  2465     ancestors or descendants of the starting revision. --follow-first
       
  2466     only follows the first parent of merge revisions.
       
  2467 
       
  2468     If no revision range is specified, the default is ``tip:0`` unless
       
  2469     --follow is set, in which case the working directory parent is
       
  2470     used as the starting revision. You can specify a revision set for
       
  2471     log, see :hg:`help revsets` for more information.
       
  2472 
       
  2473     See :hg:`help dates` for a list of formats valid for -d/--date.
       
  2474 
       
  2475     By default this command prints revision number and changeset id,
       
  2476     tags, non-trivial parents, user, date and time, and a summary for
       
  2477     each commit. When the -v/--verbose switch is used, the list of
       
  2478     changed files and full commit message are shown.
       
  2479 
       
  2480     .. note::
       
  2481        log -p/--patch may generate unexpected diff output for merge
       
  2482        changesets, as it will only compare the merge changeset against
       
  2483        its first parent. Also, only files different from BOTH parents
       
  2484        will appear in files:.
       
  2485 
       
  2486     Returns 0 on success.
       
  2487     """
       
  2488 
       
  2489     matchfn = cmdutil.match(repo, pats, opts)
       
  2490     limit = cmdutil.loglimit(opts)
       
  2491     count = 0
       
  2492 
       
  2493     endrev = None
       
  2494     if opts.get('copies') and opts.get('rev'):
       
  2495         endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
       
  2496 
       
  2497     df = False
       
  2498     if opts["date"]:
       
  2499         df = util.matchdate(opts["date"])
       
  2500 
       
  2501     branches = opts.get('branch', []) + opts.get('only_branch', [])
       
  2502     opts['branch'] = [repo.lookupbranch(b) for b in branches]
       
  2503 
       
  2504     displayer = cmdutil.show_changeset(ui, repo, opts, True)
       
  2505     def prep(ctx, fns):
       
  2506         rev = ctx.rev()
       
  2507         parents = [p for p in repo.changelog.parentrevs(rev)
       
  2508                    if p != nullrev]
       
  2509         if opts.get('no_merges') and len(parents) == 2:
       
  2510             return
       
  2511         if opts.get('only_merges') and len(parents) != 2:
       
  2512             return
       
  2513         if opts.get('branch') and ctx.branch() not in opts['branch']:
       
  2514             return
       
  2515         if df and not df(ctx.date()[0]):
       
  2516             return
       
  2517         if opts['user'] and not [k for k in opts['user']
       
  2518                                  if k.lower() in ctx.user().lower()]:
       
  2519             return
       
  2520         if opts.get('keyword'):
       
  2521             for k in [kw.lower() for kw in opts['keyword']]:
       
  2522                 if (k in ctx.user().lower() or
       
  2523                     k in ctx.description().lower() or
       
  2524                     k in " ".join(ctx.files()).lower()):
       
  2525                     break
       
  2526             else:
       
  2527                 return
       
  2528 
       
  2529         copies = None
       
  2530         if opts.get('copies') and rev:
       
  2531             copies = []
       
  2532             getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
       
  2533             for fn in ctx.files():
       
  2534                 rename = getrenamed(fn, rev)
       
  2535                 if rename:
       
  2536                     copies.append((fn, rename[0]))
       
  2537 
       
  2538         revmatchfn = None
       
  2539         if opts.get('patch') or opts.get('stat'):
       
  2540             if opts.get('follow') or opts.get('follow_first'):
       
  2541                 # note: this might be wrong when following through merges
       
  2542                 revmatchfn = cmdutil.match(repo, fns, default='path')
       
  2543             else:
       
  2544                 revmatchfn = matchfn
       
  2545 
       
  2546         displayer.show(ctx, copies=copies, matchfn=revmatchfn)
       
  2547 
       
  2548     for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
       
  2549         if count == limit:
       
  2550             break
       
  2551         if displayer.flush(ctx.rev()):
       
  2552             count += 1
       
  2553     displayer.close()
       
  2554 
       
  2555 def manifest(ui, repo, node=None, rev=None):
       
  2556     """output the current or given revision of the project manifest
       
  2557 
       
  2558     Print a list of version controlled files for the given revision.
       
  2559     If no revision is given, the first parent of the working directory
       
  2560     is used, or the null revision if no revision is checked out.
       
  2561 
       
  2562     With -v, print file permissions, symlink and executable bits.
       
  2563     With --debug, print file revision hashes.
       
  2564 
       
  2565     Returns 0 on success.
       
  2566     """
       
  2567 
       
  2568     if rev and node:
       
  2569         raise util.Abort(_("please specify just one revision"))
       
  2570 
       
  2571     if not node:
       
  2572         node = rev
       
  2573 
       
  2574     decor = {'l':'644 @ ', 'x':'755 * ', '':'644   '}
       
  2575     ctx = repo[node]
       
  2576     for f in ctx:
       
  2577         if ui.debugflag:
       
  2578             ui.write("%40s " % hex(ctx.manifest()[f]))
       
  2579         if ui.verbose:
       
  2580             ui.write(decor[ctx.flags(f)])
       
  2581         ui.write("%s\n" % f)
       
  2582 
       
  2583 def merge(ui, repo, node=None, **opts):
       
  2584     """merge working directory with another revision
       
  2585 
       
  2586     The current working directory is updated with all changes made in
       
  2587     the requested revision since the last common predecessor revision.
       
  2588 
       
  2589     Files that changed between either parent are marked as changed for
       
  2590     the next commit and a commit must be performed before any further
       
  2591     updates to the repository are allowed. The next commit will have
       
  2592     two parents.
       
  2593 
       
  2594     ``--tool`` can be used to specify the merge tool used for file
       
  2595     merges. It overrides the HGMERGE environment variable and your
       
  2596     configuration files.
       
  2597 
       
  2598     If no revision is specified, the working directory's parent is a
       
  2599     head revision, and the current branch contains exactly one other
       
  2600     head, the other head is merged with by default. Otherwise, an
       
  2601     explicit revision with which to merge with must be provided.
       
  2602 
       
  2603     :hg:`resolve` must be used to resolve unresolved files.
       
  2604 
       
  2605     To undo an uncommitted merge, use :hg:`update --clean .` which
       
  2606     will check out a clean copy of the original merge parent, losing
       
  2607     all changes.
       
  2608 
       
  2609     Returns 0 on success, 1 if there are unresolved files.
       
  2610     """
       
  2611 
       
  2612     if opts.get('rev') and node:
       
  2613         raise util.Abort(_("please specify just one revision"))
       
  2614     if not node:
       
  2615         node = opts.get('rev')
       
  2616 
       
  2617     if not node:
       
  2618         branch = repo.changectx(None).branch()
       
  2619         bheads = repo.branchheads(branch)
       
  2620         if len(bheads) > 2:
       
  2621             raise util.Abort(_(
       
  2622                 'branch \'%s\' has %d heads - '
       
  2623                 'please merge with an explicit rev\n'
       
  2624                 '(run \'hg heads .\' to see heads)')
       
  2625                 % (branch, len(bheads)))
       
  2626 
       
  2627         parent = repo.dirstate.parents()[0]
       
  2628         if len(bheads) == 1:
       
  2629             if len(repo.heads()) > 1:
       
  2630                 raise util.Abort(_(
       
  2631                     'branch \'%s\' has one head - '
       
  2632                     'please merge with an explicit rev\n'
       
  2633                     '(run \'hg heads\' to see all heads)')
       
  2634                     % branch)
       
  2635             msg = _('there is nothing to merge')
       
  2636             if parent != repo.lookup(repo[None].branch()):
       
  2637                 msg = _('%s - use "hg update" instead') % msg
       
  2638             raise util.Abort(msg)
       
  2639 
       
  2640         if parent not in bheads:
       
  2641             raise util.Abort(_('working dir not at a head rev - '
       
  2642                                'use "hg update" or merge with an explicit rev'))
       
  2643         node = parent == bheads[0] and bheads[-1] or bheads[0]
       
  2644 
       
  2645     if opts.get('preview'):
       
  2646         # find nodes that are ancestors of p2 but not of p1
       
  2647         p1 = repo.lookup('.')
       
  2648         p2 = repo.lookup(node)
       
  2649         nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
       
  2650 
       
  2651         displayer = cmdutil.show_changeset(ui, repo, opts)
       
  2652         for node in nodes:
       
  2653             displayer.show(repo[node])
       
  2654         displayer.close()
       
  2655         return 0
       
  2656 
       
  2657     try:
       
  2658         # ui.forcemerge is an internal variable, do not document
       
  2659         ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
       
  2660         return hg.merge(repo, node, force=opts.get('force'))
       
  2661     finally:
       
  2662         ui.setconfig('ui', 'forcemerge', '')
       
  2663 
       
  2664 def outgoing(ui, repo, dest=None, **opts):
       
  2665     """show changesets not found in the destination
       
  2666 
       
  2667     Show changesets not found in the specified destination repository
       
  2668     or the default push location. These are the changesets that would
       
  2669     be pushed if a push was requested.
       
  2670 
       
  2671     See pull for details of valid destination formats.
       
  2672 
       
  2673     Returns 0 if there are outgoing changes, 1 otherwise.
       
  2674     """
       
  2675     ret = hg.outgoing(ui, repo, dest, opts)
       
  2676     return ret
       
  2677 
       
  2678 def parents(ui, repo, file_=None, **opts):
       
  2679     """show the parents of the working directory or revision
       
  2680 
       
  2681     Print the working directory's parent revisions. If a revision is
       
  2682     given via -r/--rev, the parent of that revision will be printed.
       
  2683     If a file argument is given, the revision in which the file was
       
  2684     last changed (before the working directory revision or the
       
  2685     argument to --rev if given) is printed.
       
  2686 
       
  2687     Returns 0 on success.
       
  2688     """
       
  2689     rev = opts.get('rev')
       
  2690     if rev:
       
  2691         ctx = repo[rev]
       
  2692     else:
       
  2693         ctx = repo[None]
       
  2694 
       
  2695     if file_:
       
  2696         m = cmdutil.match(repo, (file_,), opts)
       
  2697         if m.anypats() or len(m.files()) != 1:
       
  2698             raise util.Abort(_('can only specify an explicit filename'))
       
  2699         file_ = m.files()[0]
       
  2700         filenodes = []
       
  2701         for cp in ctx.parents():
       
  2702             if not cp:
       
  2703                 continue
       
  2704             try:
       
  2705                 filenodes.append(cp.filenode(file_))
       
  2706             except error.LookupError:
       
  2707                 pass
       
  2708         if not filenodes:
       
  2709             raise util.Abort(_("'%s' not found in manifest!") % file_)
       
  2710         fl = repo.file(file_)
       
  2711         p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
       
  2712     else:
       
  2713         p = [cp.node() for cp in ctx.parents()]
       
  2714 
       
  2715     displayer = cmdutil.show_changeset(ui, repo, opts)
       
  2716     for n in p:
       
  2717         if n != nullid:
       
  2718             displayer.show(repo[n])
       
  2719     displayer.close()
       
  2720 
       
  2721 def paths(ui, repo, search=None):
       
  2722     """show aliases for remote repositories
       
  2723 
       
  2724     Show definition of symbolic path name NAME. If no name is given,
       
  2725     show definition of all available names.
       
  2726 
       
  2727     Path names are defined in the [paths] section of your
       
  2728     configuration file and in ``/etc/mercurial/hgrc``. If run inside a
       
  2729     repository, ``.hg/hgrc`` is used, too.
       
  2730 
       
  2731     The path names ``default`` and ``default-push`` have a special
       
  2732     meaning.  When performing a push or pull operation, they are used
       
  2733     as fallbacks if no location is specified on the command-line.
       
  2734     When ``default-push`` is set, it will be used for push and
       
  2735     ``default`` will be used for pull; otherwise ``default`` is used
       
  2736     as the fallback for both.  When cloning a repository, the clone
       
  2737     source is written as ``default`` in ``.hg/hgrc``.  Note that
       
  2738     ``default`` and ``default-push`` apply to all inbound (e.g.
       
  2739     :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
       
  2740     :hg:`bundle`) operations.
       
  2741 
       
  2742     See :hg:`help urls` for more information.
       
  2743 
       
  2744     Returns 0 on success.
       
  2745     """
       
  2746     if search:
       
  2747         for name, path in ui.configitems("paths"):
       
  2748             if name == search:
       
  2749                 ui.write("%s\n" % url.hidepassword(path))
       
  2750                 return
       
  2751         ui.warn(_("not found!\n"))
       
  2752         return 1
       
  2753     else:
       
  2754         for name, path in ui.configitems("paths"):
       
  2755             ui.write("%s = %s\n" % (name, url.hidepassword(path)))
       
  2756 
       
  2757 def postincoming(ui, repo, modheads, optupdate, checkout):
       
  2758     if modheads == 0:
       
  2759         return
       
  2760     if optupdate:
       
  2761         if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
       
  2762             return hg.update(repo, checkout)
       
  2763         else:
       
  2764             ui.status(_("not updating, since new heads added\n"))
       
  2765     if modheads > 1:
       
  2766         ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
       
  2767     else:
       
  2768         ui.status(_("(run 'hg update' to get a working copy)\n"))
       
  2769 
       
  2770 def pull(ui, repo, source="default", **opts):
       
  2771     """pull changes from the specified source
       
  2772 
       
  2773     Pull changes from a remote repository to a local one.
       
  2774 
       
  2775     This finds all changes from the repository at the specified path
       
  2776     or URL and adds them to a local repository (the current one unless
       
  2777     -R is specified). By default, this does not update the copy of the
       
  2778     project in the working directory.
       
  2779 
       
  2780     Use :hg:`incoming` if you want to see what would have been added
       
  2781     by a pull at the time you issued this command. If you then decide
       
  2782     to add those changes to the repository, you should use :hg:`pull
       
  2783     -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
       
  2784 
       
  2785     If SOURCE is omitted, the 'default' path will be used.
       
  2786     See :hg:`help urls` for more information.
       
  2787 
       
  2788     Returns 0 on success, 1 if an update had unresolved files.
       
  2789     """
       
  2790     source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
       
  2791     other = hg.repository(hg.remoteui(repo, opts), source)
       
  2792     ui.status(_('pulling from %s\n') % url.hidepassword(source))
       
  2793     revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
       
  2794     if revs:
       
  2795         try:
       
  2796             revs = [other.lookup(rev) for rev in revs]
       
  2797         except error.CapabilityError:
       
  2798             err = _("other repository doesn't support revision lookup, "
       
  2799                     "so a rev cannot be specified.")
       
  2800             raise util.Abort(err)
       
  2801 
       
  2802     modheads = repo.pull(other, heads=revs, force=opts.get('force'))
       
  2803     if checkout:
       
  2804         checkout = str(repo.changelog.rev(other.lookup(checkout)))
       
  2805     repo._subtoppath = source
       
  2806     try:
       
  2807         return postincoming(ui, repo, modheads, opts.get('update'), checkout)
       
  2808     finally:
       
  2809         del repo._subtoppath
       
  2810 
       
  2811 def push(ui, repo, dest=None, **opts):
       
  2812     """push changes to the specified destination
       
  2813 
       
  2814     Push changesets from the local repository to the specified
       
  2815     destination.
       
  2816 
       
  2817     This operation is symmetrical to pull: it is identical to a pull
       
  2818     in the destination repository from the current one.
       
  2819 
       
  2820     By default, push will not allow creation of new heads at the
       
  2821     destination, since multiple heads would make it unclear which head
       
  2822     to use. In this situation, it is recommended to pull and merge
       
  2823     before pushing.
       
  2824 
       
  2825     Use --new-branch if you want to allow push to create a new named
       
  2826     branch that is not present at the destination. This allows you to
       
  2827     only create a new branch without forcing other changes.
       
  2828 
       
  2829     Use -f/--force to override the default behavior and push all
       
  2830     changesets on all branches.
       
  2831 
       
  2832     If -r/--rev is used, the specified revision and all its ancestors
       
  2833     will be pushed to the remote repository.
       
  2834 
       
  2835     Please see :hg:`help urls` for important details about ``ssh://``
       
  2836     URLs. If DESTINATION is omitted, a default path will be used.
       
  2837 
       
  2838     Returns 0 if push was successful, 1 if nothing to push.
       
  2839     """
       
  2840     dest = ui.expandpath(dest or 'default-push', dest or 'default')
       
  2841     dest, branches = hg.parseurl(dest, opts.get('branch'))
       
  2842     revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
       
  2843     other = hg.repository(hg.remoteui(repo, opts), dest)
       
  2844     ui.status(_('pushing to %s\n') % url.hidepassword(dest))
       
  2845     if revs:
       
  2846         revs = [repo.lookup(rev) for rev in revs]
       
  2847 
       
  2848     repo._subtoppath = dest
       
  2849     try:
       
  2850         # push subrepos depth-first for coherent ordering
       
  2851         c = repo['']
       
  2852         subs = c.substate # only repos that are committed
       
  2853         for s in sorted(subs):
       
  2854             if not c.sub(s).push(opts.get('force')):
       
  2855                 return False
       
  2856     finally:
       
  2857         del repo._subtoppath
       
  2858     r = repo.push(other, opts.get('force'), revs=revs,
       
  2859                   newbranch=opts.get('new_branch'))
       
  2860     return r == 0
       
  2861 
       
  2862 def recover(ui, repo):
       
  2863     """roll back an interrupted transaction
       
  2864 
       
  2865     Recover from an interrupted commit or pull.
       
  2866 
       
  2867     This command tries to fix the repository status after an
       
  2868     interrupted operation. It should only be necessary when Mercurial
       
  2869     suggests it.
       
  2870 
       
  2871     Returns 0 if successful, 1 if nothing to recover or verify fails.
       
  2872     """
       
  2873     if repo.recover():
       
  2874         return hg.verify(repo)
       
  2875     return 1
       
  2876 
       
  2877 def remove(ui, repo, *pats, **opts):
       
  2878     """remove the specified files on the next commit
       
  2879 
       
  2880     Schedule the indicated files for removal from the repository.
       
  2881 
       
  2882     This only removes files from the current branch, not from the
       
  2883     entire project history. -A/--after can be used to remove only
       
  2884     files that have already been deleted, -f/--force can be used to
       
  2885     force deletion, and -Af can be used to remove files from the next
       
  2886     revision without deleting them from the working directory.
       
  2887 
       
  2888     The following table details the behavior of remove for different
       
  2889     file states (columns) and option combinations (rows). The file
       
  2890     states are Added [A], Clean [C], Modified [M] and Missing [!] (as
       
  2891     reported by :hg:`status`). The actions are Warn, Remove (from
       
  2892     branch) and Delete (from disk)::
       
  2893 
       
  2894              A  C  M  !
       
  2895       none   W  RD W  R
       
  2896       -f     R  RD RD R
       
  2897       -A     W  W  W  R
       
  2898       -Af    R  R  R  R
       
  2899 
       
  2900     This command schedules the files to be removed at the next commit.
       
  2901     To undo a remove before that, see :hg:`revert`.
       
  2902 
       
  2903     Returns 0 on success, 1 if any warnings encountered.
       
  2904     """
       
  2905 
       
  2906     ret = 0
       
  2907     after, force = opts.get('after'), opts.get('force')
       
  2908     if not pats and not after:
       
  2909         raise util.Abort(_('no files specified'))
       
  2910 
       
  2911     m = cmdutil.match(repo, pats, opts)
       
  2912     s = repo.status(match=m, clean=True)
       
  2913     modified, added, deleted, clean = s[0], s[1], s[3], s[6]
       
  2914 
       
  2915     for f in m.files():
       
  2916         if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
       
  2917             ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
       
  2918             ret = 1
       
  2919 
       
  2920     if force:
       
  2921         remove, forget = modified + deleted + clean, added
       
  2922     elif after:
       
  2923         remove, forget = deleted, []
       
  2924         for f in modified + added + clean:
       
  2925             ui.warn(_('not removing %s: file still exists (use -f'
       
  2926                       ' to force removal)\n') % m.rel(f))
       
  2927             ret = 1
       
  2928     else:
       
  2929         remove, forget = deleted + clean, []
       
  2930         for f in modified:
       
  2931             ui.warn(_('not removing %s: file is modified (use -f'
       
  2932                       ' to force removal)\n') % m.rel(f))
       
  2933             ret = 1
       
  2934         for f in added:
       
  2935             ui.warn(_('not removing %s: file has been marked for add (use -f'
       
  2936                       ' to force removal)\n') % m.rel(f))
       
  2937             ret = 1
       
  2938 
       
  2939     for f in sorted(remove + forget):
       
  2940         if ui.verbose or not m.exact(f):
       
  2941             ui.status(_('removing %s\n') % m.rel(f))
       
  2942 
       
  2943     repo[None].forget(forget)
       
  2944     repo[None].remove(remove, unlink=not after)
       
  2945     return ret
       
  2946 
       
  2947 def rename(ui, repo, *pats, **opts):
       
  2948     """rename files; equivalent of copy + remove
       
  2949 
       
  2950     Mark dest as copies of sources; mark sources for deletion. If dest
       
  2951     is a directory, copies are put in that directory. If dest is a
       
  2952     file, there can only be one source.
       
  2953 
       
  2954     By default, this command copies the contents of files as they
       
  2955     exist in the working directory. If invoked with -A/--after, the
       
  2956     operation is recorded, but no copying is performed.
       
  2957 
       
  2958     This command takes effect at the next commit. To undo a rename
       
  2959     before that, see :hg:`revert`.
       
  2960 
       
  2961     Returns 0 on success, 1 if errors are encountered.
       
  2962     """
       
  2963     wlock = repo.wlock(False)
       
  2964     try:
       
  2965         return cmdutil.copy(ui, repo, pats, opts, rename=True)
       
  2966     finally:
       
  2967         wlock.release()
       
  2968 
       
  2969 def resolve(ui, repo, *pats, **opts):
       
  2970     """redo merges or set/view the merge status of files
       
  2971 
       
  2972     Merges with unresolved conflicts are often the result of
       
  2973     non-interactive merging using the ``internal:merge`` configuration
       
  2974     setting, or a command-line merge tool like ``diff3``. The resolve
       
  2975     command is used to manage the files involved in a merge, after
       
  2976     :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
       
  2977     working directory must have two parents).
       
  2978 
       
  2979     The resolve command can be used in the following ways:
       
  2980 
       
  2981     - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
       
  2982       files, discarding any previous merge attempts. Re-merging is not
       
  2983       performed for files already marked as resolved. Use ``--all/-a``
       
  2984       to selects all unresolved files. ``--tool`` can be used to specify
       
  2985       the merge tool used for the given files. It overrides the HGMERGE
       
  2986       environment variable and your configuration files.
       
  2987 
       
  2988     - :hg:`resolve -m [FILE]`: mark a file as having been resolved
       
  2989       (e.g. after having manually fixed-up the files). The default is
       
  2990       to mark all unresolved files.
       
  2991 
       
  2992     - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
       
  2993       default is to mark all resolved files.
       
  2994 
       
  2995     - :hg:`resolve -l`: list files which had or still have conflicts.
       
  2996       In the printed list, ``U`` = unresolved and ``R`` = resolved.
       
  2997 
       
  2998     Note that Mercurial will not let you commit files with unresolved
       
  2999     merge conflicts. You must use :hg:`resolve -m ...` before you can
       
  3000     commit after a conflicting merge.
       
  3001 
       
  3002     Returns 0 on success, 1 if any files fail a resolve attempt.
       
  3003     """
       
  3004 
       
  3005     all, mark, unmark, show, nostatus = \
       
  3006         [opts.get(o) for o in 'all mark unmark list no_status'.split()]
       
  3007 
       
  3008     if (show and (mark or unmark)) or (mark and unmark):
       
  3009         raise util.Abort(_("too many options specified"))
       
  3010     if pats and all:
       
  3011         raise util.Abort(_("can't specify --all and patterns"))
       
  3012     if not (all or pats or show or mark or unmark):
       
  3013         raise util.Abort(_('no files or directories specified; '
       
  3014                            'use --all to remerge all files'))
       
  3015 
       
  3016     ms = mergemod.mergestate(repo)
       
  3017     m = cmdutil.match(repo, pats, opts)
       
  3018     ret = 0
       
  3019 
       
  3020     for f in ms:
       
  3021         if m(f):
       
  3022             if show:
       
  3023                 if nostatus:
       
  3024                     ui.write("%s\n" % f)
       
  3025                 else:
       
  3026                     ui.write("%s %s\n" % (ms[f].upper(), f),
       
  3027                              label='resolve.' +
       
  3028                              {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
       
  3029             elif mark:
       
  3030                 ms.mark(f, "r")
       
  3031             elif unmark:
       
  3032                 ms.mark(f, "u")
       
  3033             else:
       
  3034                 wctx = repo[None]
       
  3035                 mctx = wctx.parents()[-1]
       
  3036 
       
  3037                 # backup pre-resolve (merge uses .orig for its own purposes)
       
  3038                 a = repo.wjoin(f)
       
  3039                 util.copyfile(a, a + ".resolve")
       
  3040 
       
  3041                 try:
       
  3042                     # resolve file
       
  3043                     ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
       
  3044                     if ms.resolve(f, wctx, mctx):
       
  3045                         ret = 1
       
  3046                 finally:
       
  3047                     ui.setconfig('ui', 'forcemerge', '')
       
  3048 
       
  3049                 # replace filemerge's .orig file with our resolve file
       
  3050                 util.rename(a + ".resolve", a + ".orig")
       
  3051 
       
  3052     ms.commit()
       
  3053     return ret
       
  3054 
       
  3055 def revert(ui, repo, *pats, **opts):
       
  3056     """restore individual files or directories to an earlier state
       
  3057 
       
  3058     .. note::
       
  3059        This command is most likely not what you are looking for.
       
  3060        Revert will partially overwrite content in the working
       
  3061        directory without changing the working directory parents. Use
       
  3062        :hg:`update -r rev` to check out earlier revisions, or
       
  3063        :hg:`update --clean .` to undo a merge which has added another
       
  3064        parent.
       
  3065 
       
  3066     With no revision specified, revert the named files or directories
       
  3067     to the contents they had in the parent of the working directory.
       
  3068     This restores the contents of the affected files to an unmodified
       
  3069     state and unschedules adds, removes, copies, and renames. If the
       
  3070     working directory has two parents, you must explicitly specify a
       
  3071     revision.
       
  3072 
       
  3073     Using the -r/--rev option, revert the given files or directories
       
  3074     to their contents as of a specific revision. This can be helpful
       
  3075     to "roll back" some or all of an earlier change. See :hg:`help
       
  3076     dates` for a list of formats valid for -d/--date.
       
  3077 
       
  3078     Revert modifies the working directory. It does not commit any
       
  3079     changes, or change the parent of the working directory. If you
       
  3080     revert to a revision other than the parent of the working
       
  3081     directory, the reverted files will thus appear modified
       
  3082     afterwards.
       
  3083 
       
  3084     If a file has been deleted, it is restored. If the executable mode
       
  3085     of a file was changed, it is reset.
       
  3086 
       
  3087     If names are given, all files matching the names are reverted.
       
  3088     If no arguments are given, no files are reverted.
       
  3089 
       
  3090     Modified files are saved with a .orig suffix before reverting.
       
  3091     To disable these backups, use --no-backup.
       
  3092 
       
  3093     Returns 0 on success.
       
  3094     """
       
  3095 
       
  3096     if opts.get("date"):
       
  3097         if opts.get("rev"):
       
  3098             raise util.Abort(_("you can't specify a revision and a date"))
       
  3099         opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
       
  3100 
       
  3101     if not pats and not opts.get('all'):
       
  3102         raise util.Abort(_('no files or directories specified; '
       
  3103                            'use --all to revert the whole repo'))
       
  3104 
       
  3105     parent, p2 = repo.dirstate.parents()
       
  3106     if not opts.get('rev') and p2 != nullid:
       
  3107         raise util.Abort(_('uncommitted merge - please provide a '
       
  3108                            'specific revision'))
       
  3109     ctx = repo[opts.get('rev')]
       
  3110     node = ctx.node()
       
  3111     mf = ctx.manifest()
       
  3112     if node == parent:
       
  3113         pmf = mf
       
  3114     else:
       
  3115         pmf = None
       
  3116 
       
  3117     # need all matching names in dirstate and manifest of target rev,
       
  3118     # so have to walk both. do not print errors if files exist in one
       
  3119     # but not other.
       
  3120 
       
  3121     names = {}
       
  3122 
       
  3123     wlock = repo.wlock()
       
  3124     try:
       
  3125         # walk dirstate.
       
  3126 
       
  3127         m = cmdutil.match(repo, pats, opts)
       
  3128         m.bad = lambda x, y: False
       
  3129         for abs in repo.walk(m):
       
  3130             names[abs] = m.rel(abs), m.exact(abs)
       
  3131 
       
  3132         # walk target manifest.
       
  3133 
       
  3134         def badfn(path, msg):
       
  3135             if path in names:
       
  3136                 return
       
  3137             path_ = path + '/'
       
  3138             for f in names:
       
  3139                 if f.startswith(path_):
       
  3140                     return
       
  3141             ui.warn("%s: %s\n" % (m.rel(path), msg))
       
  3142 
       
  3143         m = cmdutil.match(repo, pats, opts)
       
  3144         m.bad = badfn
       
  3145         for abs in repo[node].walk(m):
       
  3146             if abs not in names:
       
  3147                 names[abs] = m.rel(abs), m.exact(abs)
       
  3148 
       
  3149         m = cmdutil.matchfiles(repo, names)
       
  3150         changes = repo.status(match=m)[:4]
       
  3151         modified, added, removed, deleted = map(set, changes)
       
  3152 
       
  3153         # if f is a rename, also revert the source
       
  3154         cwd = repo.getcwd()
       
  3155         for f in added:
       
  3156             src = repo.dirstate.copied(f)
       
  3157             if src and src not in names and repo.dirstate[src] == 'r':
       
  3158                 removed.add(src)
       
  3159                 names[src] = (repo.pathto(src, cwd), True)
       
  3160 
       
  3161         def removeforget(abs):
       
  3162             if repo.dirstate[abs] == 'a':
       
  3163                 return _('forgetting %s\n')
       
  3164             return _('removing %s\n')
       
  3165 
       
  3166         revert = ([], _('reverting %s\n'))
       
  3167         add = ([], _('adding %s\n'))
       
  3168         remove = ([], removeforget)
       
  3169         undelete = ([], _('undeleting %s\n'))
       
  3170 
       
  3171         disptable = (
       
  3172             # dispatch table:
       
  3173             #   file state
       
  3174             #   action if in target manifest
       
  3175             #   action if not in target manifest
       
  3176             #   make backup if in target manifest
       
  3177             #   make backup if not in target manifest
       
  3178             (modified, revert, remove, True, True),
       
  3179             (added, revert, remove, True, False),
       
  3180             (removed, undelete, None, False, False),
       
  3181             (deleted, revert, remove, False, False),
       
  3182             )
       
  3183 
       
  3184         for abs, (rel, exact) in sorted(names.items()):
       
  3185             mfentry = mf.get(abs)
       
  3186             target = repo.wjoin(abs)
       
  3187             def handle(xlist, dobackup):
       
  3188                 xlist[0].append(abs)
       
  3189                 if (dobackup and not opts.get('no_backup') and
       
  3190                     os.path.lexists(target)):
       
  3191                     bakname = "%s.orig" % rel
       
  3192                     ui.note(_('saving current version of %s as %s\n') %
       
  3193                             (rel, bakname))
       
  3194                     if not opts.get('dry_run'):
       
  3195                         util.rename(target, bakname)
       
  3196                 if ui.verbose or not exact:
       
  3197                     msg = xlist[1]
       
  3198                     if not isinstance(msg, basestring):
       
  3199                         msg = msg(abs)
       
  3200                     ui.status(msg % rel)
       
  3201             for table, hitlist, misslist, backuphit, backupmiss in disptable:
       
  3202                 if abs not in table:
       
  3203                     continue
       
  3204                 # file has changed in dirstate
       
  3205                 if mfentry:
       
  3206                     handle(hitlist, backuphit)
       
  3207                 elif misslist is not None:
       
  3208                     handle(misslist, backupmiss)
       
  3209                 break
       
  3210             else:
       
  3211                 if abs not in repo.dirstate:
       
  3212                     if mfentry:
       
  3213                         handle(add, True)
       
  3214                     elif exact:
       
  3215                         ui.warn(_('file not managed: %s\n') % rel)
       
  3216                     continue
       
  3217                 # file has not changed in dirstate
       
  3218                 if node == parent:
       
  3219                     if exact:
       
  3220                         ui.warn(_('no changes needed to %s\n') % rel)
       
  3221                     continue
       
  3222                 if pmf is None:
       
  3223                     # only need parent manifest in this unlikely case,
       
  3224                     # so do not read by default
       
  3225                     pmf = repo[parent].manifest()
       
  3226                 if abs in pmf:
       
  3227                     if mfentry:
       
  3228                         # if version of file is same in parent and target
       
  3229                         # manifests, do nothing
       
  3230                         if (pmf[abs] != mfentry or
       
  3231                             pmf.flags(abs) != mf.flags(abs)):
       
  3232                             handle(revert, False)
       
  3233                     else:
       
  3234                         handle(remove, False)
       
  3235 
       
  3236         if not opts.get('dry_run'):
       
  3237             def checkout(f):
       
  3238                 fc = ctx[f]
       
  3239                 repo.wwrite(f, fc.data(), fc.flags())
       
  3240 
       
  3241             audit_path = util.path_auditor(repo.root)
       
  3242             for f in remove[0]:
       
  3243                 if repo.dirstate[f] == 'a':
       
  3244                     repo.dirstate.forget(f)
       
  3245                     continue
       
  3246                 audit_path(f)
       
  3247                 try:
       
  3248                     util.unlink(repo.wjoin(f))
       
  3249                 except OSError:
       
  3250                     pass
       
  3251                 repo.dirstate.remove(f)
       
  3252 
       
  3253             normal = None
       
  3254             if node == parent:
       
  3255                 # We're reverting to our parent. If possible, we'd like status
       
  3256                 # to report the file as clean. We have to use normallookup for
       
  3257                 # merges to avoid losing information about merged/dirty files.
       
  3258                 if p2 != nullid:
       
  3259                     normal = repo.dirstate.normallookup
       
  3260                 else:
       
  3261                     normal = repo.dirstate.normal
       
  3262             for f in revert[0]:
       
  3263                 checkout(f)
       
  3264                 if normal:
       
  3265                     normal(f)
       
  3266 
       
  3267             for f in add[0]:
       
  3268                 checkout(f)
       
  3269                 repo.dirstate.add(f)
       
  3270 
       
  3271             normal = repo.dirstate.normallookup
       
  3272             if node == parent and p2 == nullid:
       
  3273                 normal = repo.dirstate.normal
       
  3274             for f in undelete[0]:
       
  3275                 checkout(f)
       
  3276                 normal(f)
       
  3277 
       
  3278     finally:
       
  3279         wlock.release()
       
  3280 
       
  3281 def rollback(ui, repo, **opts):
       
  3282     """roll back the last transaction (dangerous)
       
  3283 
       
  3284     This command should be used with care. There is only one level of
       
  3285     rollback, and there is no way to undo a rollback. It will also
       
  3286     restore the dirstate at the time of the last transaction, losing
       
  3287     any dirstate changes since that time. This command does not alter
       
  3288     the working directory.
       
  3289 
       
  3290     Transactions are used to encapsulate the effects of all commands
       
  3291     that create new changesets or propagate existing changesets into a
       
  3292     repository. For example, the following commands are transactional,
       
  3293     and their effects can be rolled back:
       
  3294 
       
  3295     - commit
       
  3296     - import
       
  3297     - pull
       
  3298     - push (with this repository as the destination)
       
  3299     - unbundle
       
  3300 
       
  3301     This command is not intended for use on public repositories. Once
       
  3302     changes are visible for pull by other users, rolling a transaction
       
  3303     back locally is ineffective (someone else may already have pulled
       
  3304     the changes). Furthermore, a race is possible with readers of the
       
  3305     repository; for example an in-progress pull from the repository
       
  3306     may fail if a rollback is performed.
       
  3307 
       
  3308     Returns 0 on success, 1 if no rollback data is available.
       
  3309     """
       
  3310     return repo.rollback(opts.get('dry_run'))
       
  3311 
       
  3312 def root(ui, repo):
       
  3313     """print the root (top) of the current working directory
       
  3314 
       
  3315     Print the root directory of the current repository.
       
  3316 
       
  3317     Returns 0 on success.
       
  3318     """
       
  3319     ui.write(repo.root + "\n")
       
  3320 
       
  3321 def serve(ui, repo, **opts):
       
  3322     """start stand-alone webserver
       
  3323 
       
  3324     Start a local HTTP repository browser and pull server. You can use
       
  3325     this for ad-hoc sharing and browsing of repositories. It is
       
  3326     recommended to use a real web server to serve a repository for
       
  3327     longer periods of time.
       
  3328 
       
  3329     Please note that the server does not implement access control.
       
  3330     This means that, by default, anybody can read from the server and
       
  3331     nobody can write to it by default. Set the ``web.allow_push``
       
  3332     option to ``*`` to allow everybody to push to the server. You
       
  3333     should use a real web server if you need to authenticate users.
       
  3334 
       
  3335     By default, the server logs accesses to stdout and errors to
       
  3336     stderr. Use the -A/--accesslog and -E/--errorlog options to log to
       
  3337     files.
       
  3338 
       
  3339     To have the server choose a free port number to listen on, specify
       
  3340     a port number of 0; in this case, the server will print the port
       
  3341     number it uses.
       
  3342 
       
  3343     Returns 0 on success.
       
  3344     """
       
  3345 
       
  3346     if opts["stdio"]:
       
  3347         if repo is None:
       
  3348             raise error.RepoError(_("There is no Mercurial repository here"
       
  3349                               " (.hg not found)"))
       
  3350         s = sshserver.sshserver(ui, repo)
       
  3351         s.serve_forever()
       
  3352 
       
  3353     # this way we can check if something was given in the command-line
       
  3354     if opts.get('port'):
       
  3355         opts['port'] = util.getport(opts.get('port'))
       
  3356 
       
  3357     baseui = repo and repo.baseui or ui
       
  3358     optlist = ("name templates style address port prefix ipv6"
       
  3359                " accesslog errorlog certificate encoding")
       
  3360     for o in optlist.split():
       
  3361         val = opts.get(o, '')
       
  3362         if val in (None, ''): # should check against default options instead
       
  3363             continue
       
  3364         baseui.setconfig("web", o, val)
       
  3365         if repo and repo.ui != baseui:
       
  3366             repo.ui.setconfig("web", o, val)
       
  3367 
       
  3368     o = opts.get('web_conf') or opts.get('webdir_conf')
       
  3369     if not o:
       
  3370         if not repo:
       
  3371             raise error.RepoError(_("There is no Mercurial repository"
       
  3372                                     " here (.hg not found)"))
       
  3373         o = repo.root
       
  3374 
       
  3375     app = hgweb.hgweb(o, baseui=ui)
       
  3376 
       
  3377     class service(object):
       
  3378         def init(self):
       
  3379             util.set_signal_handler()
       
  3380             self.httpd = hgweb.server.create_server(ui, app)
       
  3381 
       
  3382             if opts['port'] and not ui.verbose:
       
  3383                 return
       
  3384 
       
  3385             if self.httpd.prefix:
       
  3386                 prefix = self.httpd.prefix.strip('/') + '/'
       
  3387             else:
       
  3388                 prefix = ''
       
  3389 
       
  3390             port = ':%d' % self.httpd.port
       
  3391             if port == ':80':
       
  3392                 port = ''
       
  3393 
       
  3394             bindaddr = self.httpd.addr
       
  3395             if bindaddr == '0.0.0.0':
       
  3396                 bindaddr = '*'
       
  3397             elif ':' in bindaddr: # IPv6
       
  3398                 bindaddr = '[%s]' % bindaddr
       
  3399 
       
  3400             fqaddr = self.httpd.fqaddr
       
  3401             if ':' in fqaddr:
       
  3402                 fqaddr = '[%s]' % fqaddr
       
  3403             if opts['port']:
       
  3404                 write = ui.status
       
  3405             else:
       
  3406                 write = ui.write
       
  3407             write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
       
  3408                   (fqaddr, port, prefix, bindaddr, self.httpd.port))
       
  3409 
       
  3410         def run(self):
       
  3411             self.httpd.serve_forever()
       
  3412 
       
  3413     service = service()
       
  3414 
       
  3415     cmdutil.service(opts, initfn=service.init, runfn=service.run)
       
  3416 
       
  3417 def status(ui, repo, *pats, **opts):
       
  3418     """show changed files in the working directory
       
  3419 
       
  3420     Show status of files in the repository. If names are given, only
       
  3421     files that match are shown. Files that are clean or ignored or
       
  3422     the source of a copy/move operation, are not listed unless
       
  3423     -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
       
  3424     Unless options described with "show only ..." are given, the
       
  3425     options -mardu are used.
       
  3426 
       
  3427     Option -q/--quiet hides untracked (unknown and ignored) files
       
  3428     unless explicitly requested with -u/--unknown or -i/--ignored.
       
  3429 
       
  3430     .. note::
       
  3431        status may appear to disagree with diff if permissions have
       
  3432        changed or a merge has occurred. The standard diff format does
       
  3433        not report permission changes and diff only reports changes
       
  3434        relative to one merge parent.
       
  3435 
       
  3436     If one revision is given, it is used as the base revision.
       
  3437     If two revisions are given, the differences between them are
       
  3438     shown. The --change option can also be used as a shortcut to list
       
  3439     the changed files of a revision from its first parent.
       
  3440 
       
  3441     The codes used to show the status of files are::
       
  3442 
       
  3443       M = modified
       
  3444       A = added
       
  3445       R = removed
       
  3446       C = clean
       
  3447       ! = missing (deleted by non-hg command, but still tracked)
       
  3448       ? = not tracked
       
  3449       I = ignored
       
  3450         = origin of the previous file listed as A (added)
       
  3451 
       
  3452     Returns 0 on success.
       
  3453     """
       
  3454 
       
  3455     revs = opts.get('rev')
       
  3456     change = opts.get('change')
       
  3457 
       
  3458     if revs and change:
       
  3459         msg = _('cannot specify --rev and --change at the same time')
       
  3460         raise util.Abort(msg)
       
  3461     elif change:
       
  3462         node2 = repo.lookup(change)
       
  3463         node1 = repo[node2].parents()[0].node()
       
  3464     else:
       
  3465         node1, node2 = cmdutil.revpair(repo, revs)
       
  3466 
       
  3467     cwd = (pats and repo.getcwd()) or ''
       
  3468     end = opts.get('print0') and '\0' or '\n'
       
  3469     copy = {}
       
  3470     states = 'modified added removed deleted unknown ignored clean'.split()
       
  3471     show = [k for k in states if opts.get(k)]
       
  3472     if opts.get('all'):
       
  3473         show += ui.quiet and (states[:4] + ['clean']) or states
       
  3474     if not show:
       
  3475         show = ui.quiet and states[:4] or states[:5]
       
  3476 
       
  3477     stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
       
  3478                        'ignored' in show, 'clean' in show, 'unknown' in show,
       
  3479                        opts.get('subrepos'))
       
  3480     changestates = zip(states, 'MAR!?IC', stat)
       
  3481 
       
  3482     if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
       
  3483         ctxn = repo[nullid]
       
  3484         ctx1 = repo[node1]
       
  3485         ctx2 = repo[node2]
       
  3486         added = stat[1]
       
  3487         if node2 is None:
       
  3488             added = stat[0] + stat[1] # merged?
       
  3489 
       
  3490         for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
       
  3491             if k in added:
       
  3492                 copy[k] = v
       
  3493             elif v in added:
       
  3494                 copy[v] = k
       
  3495 
       
  3496     for state, char, files in changestates:
       
  3497         if state in show:
       
  3498             format = "%s %%s%s" % (char, end)
       
  3499             if opts.get('no_status'):
       
  3500                 format = "%%s%s" % end
       
  3501 
       
  3502             for f in files:
       
  3503                 ui.write(format % repo.pathto(f, cwd),
       
  3504                          label='status.' + state)
       
  3505                 if f in copy:
       
  3506                     ui.write('  %s%s' % (repo.pathto(copy[f], cwd), end),
       
  3507                              label='status.copied')
       
  3508 
       
  3509 def summary(ui, repo, **opts):
       
  3510     """summarize working directory state
       
  3511 
       
  3512     This generates a brief summary of the working directory state,
       
  3513     including parents, branch, commit status, and available updates.
       
  3514 
       
  3515     With the --remote option, this will check the default paths for
       
  3516     incoming and outgoing changes. This can be time-consuming.
       
  3517 
       
  3518     Returns 0 on success.
       
  3519     """
       
  3520 
       
  3521     ctx = repo[None]
       
  3522     parents = ctx.parents()
       
  3523     pnode = parents[0].node()
       
  3524 
       
  3525     for p in parents:
       
  3526         # label with log.changeset (instead of log.parent) since this
       
  3527         # shows a working directory parent *changeset*:
       
  3528         ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
       
  3529                  label='log.changeset')
       
  3530         ui.write(' '.join(p.tags()), label='log.tag')
       
  3531         if p.rev() == -1:
       
  3532             if not len(repo):
       
  3533                 ui.write(_(' (empty repository)'))
       
  3534             else:
       
  3535                 ui.write(_(' (no revision checked out)'))
       
  3536         ui.write('\n')
       
  3537         if p.description():
       
  3538             ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
       
  3539                       label='log.summary')
       
  3540 
       
  3541     branch = ctx.branch()
       
  3542     bheads = repo.branchheads(branch)
       
  3543     m = _('branch: %s\n') % branch
       
  3544     if branch != 'default':
       
  3545         ui.write(m, label='log.branch')
       
  3546     else:
       
  3547         ui.status(m, label='log.branch')
       
  3548 
       
  3549     st = list(repo.status(unknown=True))[:6]
       
  3550 
       
  3551     c = repo.dirstate.copies()
       
  3552     copied, renamed = [], []
       
  3553     for d, s in c.iteritems():
       
  3554         if s in st[2]:
       
  3555             st[2].remove(s)
       
  3556             renamed.append(d)
       
  3557         else:
       
  3558             copied.append(d)
       
  3559         if d in st[1]:
       
  3560             st[1].remove(d)
       
  3561     st.insert(3, renamed)
       
  3562     st.insert(4, copied)
       
  3563 
       
  3564     ms = mergemod.mergestate(repo)
       
  3565     st.append([f for f in ms if ms[f] == 'u'])
       
  3566 
       
  3567     subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
       
  3568     st.append(subs)
       
  3569 
       
  3570     labels = [ui.label(_('%d modified'), 'status.modified'),
       
  3571               ui.label(_('%d added'), 'status.added'),
       
  3572               ui.label(_('%d removed'), 'status.removed'),
       
  3573               ui.label(_('%d renamed'), 'status.copied'),
       
  3574               ui.label(_('%d copied'), 'status.copied'),
       
  3575               ui.label(_('%d deleted'), 'status.deleted'),
       
  3576               ui.label(_('%d unknown'), 'status.unknown'),
       
  3577               ui.label(_('%d ignored'), 'status.ignored'),
       
  3578               ui.label(_('%d unresolved'), 'resolve.unresolved'),
       
  3579               ui.label(_('%d subrepos'), 'status.modified')]
       
  3580     t = []
       
  3581     for s, l in zip(st, labels):
       
  3582         if s:
       
  3583             t.append(l % len(s))
       
  3584 
       
  3585     t = ', '.join(t)
       
  3586     cleanworkdir = False
       
  3587 
       
  3588     if len(parents) > 1:
       
  3589         t += _(' (merge)')
       
  3590     elif branch != parents[0].branch():
       
  3591         t += _(' (new branch)')
       
  3592     elif (parents[0].extra().get('close') and
       
  3593           pnode in repo.branchheads(branch, closed=True)):
       
  3594         t += _(' (head closed)')
       
  3595     elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
       
  3596         t += _(' (clean)')
       
  3597         cleanworkdir = True
       
  3598     elif pnode not in bheads:
       
  3599         t += _(' (new branch head)')
       
  3600 
       
  3601     if cleanworkdir:
       
  3602         ui.status(_('commit: %s\n') % t.strip())
       
  3603     else:
       
  3604         ui.write(_('commit: %s\n') % t.strip())
       
  3605 
       
  3606     # all ancestors of branch heads - all ancestors of parent = new csets
       
  3607     new = [0] * len(repo)
       
  3608     cl = repo.changelog
       
  3609     for a in [cl.rev(n) for n in bheads]:
       
  3610         new[a] = 1
       
  3611     for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
       
  3612         new[a] = 1
       
  3613     for a in [p.rev() for p in parents]:
       
  3614         if a >= 0:
       
  3615             new[a] = 0
       
  3616     for a in cl.ancestors(*[p.rev() for p in parents]):
       
  3617         new[a] = 0
       
  3618     new = sum(new)
       
  3619 
       
  3620     if new == 0:
       
  3621         ui.status(_('update: (current)\n'))
       
  3622     elif pnode not in bheads:
       
  3623         ui.write(_('update: %d new changesets (update)\n') % new)
       
  3624     else:
       
  3625         ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
       
  3626                  (new, len(bheads)))
       
  3627 
       
  3628     if opts.get('remote'):
       
  3629         t = []
       
  3630         source, branches = hg.parseurl(ui.expandpath('default'))
       
  3631         other = hg.repository(hg.remoteui(repo, {}), source)
       
  3632         revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
       
  3633         ui.debug('comparing with %s\n' % url.hidepassword(source))
       
  3634         repo.ui.pushbuffer()
       
  3635         common, incoming, rheads = discovery.findcommonincoming(repo, other)
       
  3636         repo.ui.popbuffer()
       
  3637         if incoming:
       
  3638             t.append(_('1 or more incoming'))
       
  3639 
       
  3640         dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
       
  3641         revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
       
  3642         other = hg.repository(hg.remoteui(repo, {}), dest)
       
  3643         ui.debug('comparing with %s\n' % url.hidepassword(dest))
       
  3644         repo.ui.pushbuffer()
       
  3645         o = discovery.findoutgoing(repo, other)
       
  3646         repo.ui.popbuffer()
       
  3647         o = repo.changelog.nodesbetween(o, None)[0]
       
  3648         if o:
       
  3649             t.append(_('%d outgoing') % len(o))
       
  3650 
       
  3651         if t:
       
  3652             ui.write(_('remote: %s\n') % (', '.join(t)))
       
  3653         else:
       
  3654             ui.status(_('remote: (synced)\n'))
       
  3655 
       
  3656 def tag(ui, repo, name1, *names, **opts):
       
  3657     """add one or more tags for the current or given revision
       
  3658 
       
  3659     Name a particular revision using <name>.
       
  3660 
       
  3661     Tags are used to name particular revisions of the repository and are
       
  3662     very useful to compare different revisions, to go back to significant
       
  3663     earlier versions or to mark branch points as releases, etc. Changing
       
  3664     an existing tag is normally disallowed; use -f/--force to override.
       
  3665 
       
  3666     If no revision is given, the parent of the working directory is
       
  3667     used, or tip if no revision is checked out.
       
  3668 
       
  3669     To facilitate version control, distribution, and merging of tags,
       
  3670     they are stored as a file named ".hgtags" which is managed similarly
       
  3671     to other project files and can be hand-edited if necessary. This
       
  3672     also means that tagging creates a new commit. The file
       
  3673     ".hg/localtags" is used for local tags (not shared among
       
  3674     repositories).
       
  3675 
       
  3676     Tag commits are usually made at the head of a branch. If the parent
       
  3677     of the working directory is not a branch head, :hg:`tag` aborts; use
       
  3678     -f/--force to force the tag commit to be based on a non-head
       
  3679     changeset.
       
  3680 
       
  3681     See :hg:`help dates` for a list of formats valid for -d/--date.
       
  3682 
       
  3683     Since tag names have priority over branch names during revision
       
  3684     lookup, using an existing branch name as a tag name is discouraged.
       
  3685 
       
  3686     Returns 0 on success.
       
  3687     """
       
  3688 
       
  3689     rev_ = "."
       
  3690     names = [t.strip() for t in (name1,) + names]
       
  3691     if len(names) != len(set(names)):
       
  3692         raise util.Abort(_('tag names must be unique'))
       
  3693     for n in names:
       
  3694         if n in ['tip', '.', 'null']:
       
  3695             raise util.Abort(_('the name \'%s\' is reserved') % n)
       
  3696         if not n:
       
  3697             raise util.Abort(_('tag names cannot consist entirely of whitespace'))
       
  3698     if opts.get('rev') and opts.get('remove'):
       
  3699         raise util.Abort(_("--rev and --remove are incompatible"))
       
  3700     if opts.get('rev'):
       
  3701         rev_ = opts['rev']
       
  3702     message = opts.get('message')
       
  3703     if opts.get('remove'):
       
  3704         expectedtype = opts.get('local') and 'local' or 'global'
       
  3705         for n in names:
       
  3706             if not repo.tagtype(n):
       
  3707                 raise util.Abort(_('tag \'%s\' does not exist') % n)
       
  3708             if repo.tagtype(n) != expectedtype:
       
  3709                 if expectedtype == 'global':
       
  3710                     raise util.Abort(_('tag \'%s\' is not a global tag') % n)
       
  3711                 else:
       
  3712                     raise util.Abort(_('tag \'%s\' is not a local tag') % n)
       
  3713         rev_ = nullid
       
  3714         if not message:
       
  3715             # we don't translate commit messages
       
  3716             message = 'Removed tag %s' % ', '.join(names)
       
  3717     elif not opts.get('force'):
       
  3718         for n in names:
       
  3719             if n in repo.tags():
       
  3720                 raise util.Abort(_('tag \'%s\' already exists '
       
  3721                                    '(use -f to force)') % n)
       
  3722     if not opts.get('local'):
       
  3723         p1, p2 = repo.dirstate.parents()
       
  3724         if p2 != nullid:
       
  3725             raise util.Abort(_('uncommitted merge'))
       
  3726         bheads = repo.branchheads()
       
  3727         if not opts.get('force') and bheads and p1 not in bheads:
       
  3728             raise util.Abort(_('not at a branch head (use -f to force)'))
       
  3729     r = repo[rev_].node()
       
  3730 
       
  3731     if not message:
       
  3732         # we don't translate commit messages
       
  3733         message = ('Added tag %s for changeset %s' %
       
  3734                    (', '.join(names), short(r)))
       
  3735 
       
  3736     date = opts.get('date')
       
  3737     if date:
       
  3738         date = util.parsedate(date)
       
  3739 
       
  3740     if opts.get('edit'):
       
  3741         message = ui.edit(message, ui.username())
       
  3742 
       
  3743     repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
       
  3744 
       
  3745 def tags(ui, repo):
       
  3746     """list repository tags
       
  3747 
       
  3748     This lists both regular and local tags. When the -v/--verbose
       
  3749     switch is used, a third column "local" is printed for local tags.
       
  3750 
       
  3751     Returns 0 on success.
       
  3752     """
       
  3753 
       
  3754     hexfunc = ui.debugflag and hex or short
       
  3755     tagtype = ""
       
  3756 
       
  3757     for t, n in reversed(repo.tagslist()):
       
  3758         if ui.quiet:
       
  3759             ui.write("%s\n" % t)
       
  3760             continue
       
  3761 
       
  3762         try:
       
  3763             hn = hexfunc(n)
       
  3764             r = "%5d:%s" % (repo.changelog.rev(n), hn)
       
  3765         except error.LookupError:
       
  3766             r = "    ?:%s" % hn
       
  3767         else:
       
  3768             spaces = " " * (30 - encoding.colwidth(t))
       
  3769             if ui.verbose:
       
  3770                 if repo.tagtype(t) == 'local':
       
  3771                     tagtype = " local"
       
  3772                 else:
       
  3773                     tagtype = ""
       
  3774             ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
       
  3775 
       
  3776 def tip(ui, repo, **opts):
       
  3777     """show the tip revision
       
  3778 
       
  3779     The tip revision (usually just called the tip) is the changeset
       
  3780     most recently added to the repository (and therefore the most
       
  3781     recently changed head).
       
  3782 
       
  3783     If you have just made a commit, that commit will be the tip. If
       
  3784     you have just pulled changes from another repository, the tip of
       
  3785     that repository becomes the current tip. The "tip" tag is special
       
  3786     and cannot be renamed or assigned to a different changeset.
       
  3787 
       
  3788     Returns 0 on success.
       
  3789     """
       
  3790     displayer = cmdutil.show_changeset(ui, repo, opts)
       
  3791     displayer.show(repo[len(repo) - 1])
       
  3792     displayer.close()
       
  3793 
       
  3794 def unbundle(ui, repo, fname1, *fnames, **opts):
       
  3795     """apply one or more changegroup files
       
  3796 
       
  3797     Apply one or more compressed changegroup files generated by the
       
  3798     bundle command.
       
  3799 
       
  3800     Returns 0 on success, 1 if an update has unresolved files.
       
  3801     """
       
  3802     fnames = (fname1,) + fnames
       
  3803 
       
  3804     lock = repo.lock()
       
  3805     try:
       
  3806         for fname in fnames:
       
  3807             f = url.open(ui, fname)
       
  3808             gen = changegroup.readbundle(f, fname)
       
  3809             modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
       
  3810                                            lock=lock)
       
  3811     finally:
       
  3812         lock.release()
       
  3813 
       
  3814     return postincoming(ui, repo, modheads, opts.get('update'), None)
       
  3815 
       
  3816 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
       
  3817     """update working directory (or switch revisions)
       
  3818 
       
  3819     Update the repository's working directory to the specified
       
  3820     changeset. If no changeset is specified, update to the tip of the
       
  3821     current named branch.
       
  3822 
       
  3823     If the changeset is not a descendant of the working directory's
       
  3824     parent, the update is aborted. With the -c/--check option, the
       
  3825     working directory is checked for uncommitted changes; if none are
       
  3826     found, the working directory is updated to the specified
       
  3827     changeset.
       
  3828 
       
  3829     The following rules apply when the working directory contains
       
  3830     uncommitted changes:
       
  3831 
       
  3832     1. If neither -c/--check nor -C/--clean is specified, and if
       
  3833        the requested changeset is an ancestor or descendant of
       
  3834        the working directory's parent, the uncommitted changes
       
  3835        are merged into the requested changeset and the merged
       
  3836        result is left uncommitted. If the requested changeset is
       
  3837        not an ancestor or descendant (that is, it is on another
       
  3838        branch), the update is aborted and the uncommitted changes
       
  3839        are preserved.
       
  3840 
       
  3841     2. With the -c/--check option, the update is aborted and the
       
  3842        uncommitted changes are preserved.
       
  3843 
       
  3844     3. With the -C/--clean option, uncommitted changes are discarded and
       
  3845        the working directory is updated to the requested changeset.
       
  3846 
       
  3847     Use null as the changeset to remove the working directory (like
       
  3848     :hg:`clone -U`).
       
  3849 
       
  3850     If you want to update just one file to an older changeset, use
       
  3851     :hg:`revert`.
       
  3852 
       
  3853     See :hg:`help dates` for a list of formats valid for -d/--date.
       
  3854 
       
  3855     Returns 0 on success, 1 if there are unresolved files.
       
  3856     """
       
  3857     if rev and node:
       
  3858         raise util.Abort(_("please specify just one revision"))
       
  3859 
       
  3860     if not rev:
       
  3861         rev = node
       
  3862 
       
  3863     rev = cmdutil.revsingle(repo, rev, rev).rev()
       
  3864 
       
  3865     if check and clean:
       
  3866         raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
       
  3867 
       
  3868     if check:
       
  3869         # we could use dirty() but we can ignore merge and branch trivia
       
  3870         c = repo[None]
       
  3871         if c.modified() or c.added() or c.removed():
       
  3872             raise util.Abort(_("uncommitted local changes"))
       
  3873 
       
  3874     if date:
       
  3875         if rev:
       
  3876             raise util.Abort(_("you can't specify a revision and a date"))
       
  3877         rev = cmdutil.finddate(ui, repo, date)
       
  3878 
       
  3879     if clean or check:
       
  3880         return hg.clean(repo, rev)
       
  3881     else:
       
  3882         return hg.update(repo, rev)
       
  3883 
       
  3884 def verify(ui, repo):
       
  3885     """verify the integrity of the repository
       
  3886 
       
  3887     Verify the integrity of the current repository.
       
  3888 
       
  3889     This will perform an extensive check of the repository's
       
  3890     integrity, validating the hashes and checksums of each entry in
       
  3891     the changelog, manifest, and tracked files, as well as the
       
  3892     integrity of their crosslinks and indices.
       
  3893 
       
  3894     Returns 0 on success, 1 if errors are encountered.
       
  3895     """
       
  3896     return hg.verify(repo)
       
  3897 
       
  3898 def version_(ui):
       
  3899     """output version and copyright information"""
       
  3900     ui.write(_("Mercurial Distributed SCM (version %s)\n")
       
  3901              % util.version())
       
  3902     ui.status(_(
       
  3903         "(see http://mercurial.selenic.com for more information)\n"
       
  3904         "\nCopyright (C) 2005-2010 Matt Mackall and others\n"
       
  3905         "This is free software; see the source for copying conditions. "
       
  3906         "There is NO\nwarranty; "
       
  3907         "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
       
  3908     ))
       
  3909 
       
  3910 # Command options and aliases are listed here, alphabetically
       
  3911 
       
  3912 globalopts = [
       
  3913     ('R', 'repository', '',
       
  3914      _('repository root directory or name of overlay bundle file'),
       
  3915      _('REPO')),
       
  3916     ('', 'cwd', '',
       
  3917      _('change working directory'), _('DIR')),
       
  3918     ('y', 'noninteractive', None,
       
  3919      _('do not prompt, assume \'yes\' for any required answers')),
       
  3920     ('q', 'quiet', None, _('suppress output')),
       
  3921     ('v', 'verbose', None, _('enable additional output')),
       
  3922     ('', 'config', [],
       
  3923      _('set/override config option (use \'section.name=value\')'),
       
  3924      _('CONFIG')),
       
  3925     ('', 'debug', None, _('enable debugging output')),
       
  3926     ('', 'debugger', None, _('start debugger')),
       
  3927     ('', 'encoding', encoding.encoding, _('set the charset encoding'),
       
  3928      _('ENCODE')),
       
  3929     ('', 'encodingmode', encoding.encodingmode,
       
  3930      _('set the charset encoding mode'), _('MODE')),
       
  3931     ('', 'traceback', None, _('always print a traceback on exception')),
       
  3932     ('', 'time', None, _('time how long the command takes')),
       
  3933     ('', 'profile', None, _('print command execution profile')),
       
  3934     ('', 'version', None, _('output version information and exit')),
       
  3935     ('h', 'help', None, _('display help and exit')),
       
  3936 ]
       
  3937 
       
  3938 dryrunopts = [('n', 'dry-run', None,
       
  3939                _('do not perform actions, just print output'))]
       
  3940 
       
  3941 remoteopts = [
       
  3942     ('e', 'ssh', '',
       
  3943      _('specify ssh command to use'), _('CMD')),
       
  3944     ('', 'remotecmd', '',
       
  3945      _('specify hg command to run on the remote side'), _('CMD')),
       
  3946 ]
       
  3947 
       
  3948 walkopts = [
       
  3949     ('I', 'include', [],
       
  3950      _('include names matching the given patterns'), _('PATTERN')),
       
  3951     ('X', 'exclude', [],
       
  3952      _('exclude names matching the given patterns'), _('PATTERN')),
       
  3953 ]
       
  3954 
       
  3955 commitopts = [
       
  3956     ('m', 'message', '',
       
  3957      _('use text as commit message'), _('TEXT')),
       
  3958     ('l', 'logfile', '',
       
  3959      _('read commit message from file'), _('FILE')),
       
  3960 ]
       
  3961 
       
  3962 commitopts2 = [
       
  3963     ('d', 'date', '',
       
  3964      _('record datecode as commit date'), _('DATE')),
       
  3965     ('u', 'user', '',
       
  3966      _('record the specified user as committer'), _('USER')),
       
  3967 ]
       
  3968 
       
  3969 templateopts = [
       
  3970     ('', 'style', '',
       
  3971      _('display using template map file'), _('STYLE')),
       
  3972     ('', 'template', '',
       
  3973      _('display with template'), _('TEMPLATE')),
       
  3974 ]
       
  3975 
       
  3976 logopts = [
       
  3977     ('p', 'patch', None, _('show patch')),
       
  3978     ('g', 'git', None, _('use git extended diff format')),
       
  3979     ('l', 'limit', '',
       
  3980      _('limit number of changes displayed'), _('NUM')),
       
  3981     ('M', 'no-merges', None, _('do not show merges')),
       
  3982     ('', 'stat', None, _('output diffstat-style summary of changes')),
       
  3983 ] + templateopts
       
  3984 
       
  3985 diffopts = [
       
  3986     ('a', 'text', None, _('treat all files as text')),
       
  3987     ('g', 'git', None, _('use git extended diff format')),
       
  3988     ('', 'nodates', None, _('omit dates from diff headers'))
       
  3989 ]
       
  3990 
       
  3991 diffopts2 = [
       
  3992     ('p', 'show-function', None, _('show which function each change is in')),
       
  3993     ('', 'reverse', None, _('produce a diff that undoes the changes')),
       
  3994     ('w', 'ignore-all-space', None,
       
  3995      _('ignore white space when comparing lines')),
       
  3996     ('b', 'ignore-space-change', None,
       
  3997      _('ignore changes in the amount of white space')),
       
  3998     ('B', 'ignore-blank-lines', None,
       
  3999      _('ignore changes whose lines are all blank')),
       
  4000     ('U', 'unified', '',
       
  4001      _('number of lines of context to show'), _('NUM')),
       
  4002     ('', 'stat', None, _('output diffstat-style summary of changes')),
       
  4003 ]
       
  4004 
       
  4005 similarityopts = [
       
  4006     ('s', 'similarity', '',
       
  4007      _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
       
  4008 ]
       
  4009 
       
  4010 subrepoopts = [
       
  4011     ('S', 'subrepos', None,
       
  4012      _('recurse into subrepositories'))
       
  4013 ]
       
  4014 
       
  4015 table = {
       
  4016     "^add": (add, walkopts + subrepoopts + dryrunopts,
       
  4017              _('[OPTION]... [FILE]...')),
       
  4018     "addremove":
       
  4019         (addremove, similarityopts + walkopts + dryrunopts,
       
  4020          _('[OPTION]... [FILE]...')),
       
  4021     "^annotate|blame":
       
  4022         (annotate,
       
  4023          [('r', 'rev', '',
       
  4024            _('annotate the specified revision'), _('REV')),
       
  4025           ('', 'follow', None,
       
  4026            _('follow copies/renames and list the filename (DEPRECATED)')),
       
  4027           ('', 'no-follow', None, _("don't follow copies and renames")),
       
  4028           ('a', 'text', None, _('treat all files as text')),
       
  4029           ('u', 'user', None, _('list the author (long with -v)')),
       
  4030           ('f', 'file', None, _('list the filename')),
       
  4031           ('d', 'date', None, _('list the date (short with -q)')),
       
  4032           ('n', 'number', None, _('list the revision number (default)')),
       
  4033           ('c', 'changeset', None, _('list the changeset')),
       
  4034           ('l', 'line-number', None,
       
  4035            _('show line number at the first appearance'))
       
  4036          ] + walkopts,
       
  4037          _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
       
  4038     "archive":
       
  4039         (archive,
       
  4040          [('', 'no-decode', None, _('do not pass files through decoders')),
       
  4041           ('p', 'prefix', '',
       
  4042            _('directory prefix for files in archive'), _('PREFIX')),
       
  4043           ('r', 'rev', '',
       
  4044            _('revision to distribute'), _('REV')),
       
  4045           ('t', 'type', '',
       
  4046            _('type of distribution to create'), _('TYPE')),
       
  4047          ] + subrepoopts + walkopts,
       
  4048          _('[OPTION]... DEST')),
       
  4049     "backout":
       
  4050         (backout,
       
  4051          [('', 'merge', None,
       
  4052            _('merge with old dirstate parent after backout')),
       
  4053           ('', 'parent', '',
       
  4054            _('parent to choose when backing out merge'), _('REV')),
       
  4055           ('t', 'tool', '',
       
  4056            _('specify merge tool')),
       
  4057           ('r', 'rev', '',
       
  4058            _('revision to backout'), _('REV')),
       
  4059          ] + walkopts + commitopts + commitopts2,
       
  4060          _('[OPTION]... [-r] REV')),
       
  4061     "bisect":
       
  4062         (bisect,
       
  4063          [('r', 'reset', False, _('reset bisect state')),
       
  4064           ('g', 'good', False, _('mark changeset good')),
       
  4065           ('b', 'bad', False, _('mark changeset bad')),
       
  4066           ('s', 'skip', False, _('skip testing changeset')),
       
  4067           ('c', 'command', '',
       
  4068            _('use command to check changeset state'), _('CMD')),
       
  4069           ('U', 'noupdate', False, _('do not update to target'))],
       
  4070          _("[-gbsr] [-U] [-c CMD] [REV]")),
       
  4071     "branch":
       
  4072         (branch,
       
  4073          [('f', 'force', None,
       
  4074            _('set branch name even if it shadows an existing branch')),
       
  4075           ('C', 'clean', None, _('reset branch name to parent branch name'))],
       
  4076          _('[-fC] [NAME]')),
       
  4077     "branches":
       
  4078         (branches,
       
  4079          [('a', 'active', False,
       
  4080            _('show only branches that have unmerged heads')),
       
  4081           ('c', 'closed', False,
       
  4082            _('show normal and closed branches'))],
       
  4083          _('[-ac]')),
       
  4084     "bundle":
       
  4085         (bundle,
       
  4086          [('f', 'force', None,
       
  4087            _('run even when the destination is unrelated')),
       
  4088           ('r', 'rev', [],
       
  4089            _('a changeset intended to be added to the destination'),
       
  4090            _('REV')),
       
  4091           ('b', 'branch', [],
       
  4092            _('a specific branch you would like to bundle'),
       
  4093            _('BRANCH')),
       
  4094           ('', 'base', [],
       
  4095            _('a base changeset assumed to be available at the destination'),
       
  4096            _('REV')),
       
  4097           ('a', 'all', None, _('bundle all changesets in the repository')),
       
  4098           ('t', 'type', 'bzip2',
       
  4099            _('bundle compression type to use'), _('TYPE')),
       
  4100          ] + remoteopts,
       
  4101          _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
       
  4102     "cat":
       
  4103         (cat,
       
  4104          [('o', 'output', '',
       
  4105           _('print output to file with formatted name'), _('FORMAT')),
       
  4106           ('r', 'rev', '',
       
  4107            _('print the given revision'), _('REV')),
       
  4108           ('', 'decode', None, _('apply any matching decode filter')),
       
  4109          ] + walkopts,
       
  4110          _('[OPTION]... FILE...')),
       
  4111     "^clone":
       
  4112         (clone,
       
  4113          [('U', 'noupdate', None,
       
  4114           _('the clone will include an empty working copy (only a repository)')),
       
  4115           ('u', 'updaterev', '',
       
  4116            _('revision, tag or branch to check out'), _('REV')),
       
  4117           ('r', 'rev', [],
       
  4118            _('include the specified changeset'), _('REV')),
       
  4119           ('b', 'branch', [],
       
  4120            _('clone only the specified branch'), _('BRANCH')),
       
  4121           ('', 'pull', None, _('use pull protocol to copy metadata')),
       
  4122           ('', 'uncompressed', None,
       
  4123            _('use uncompressed transfer (fast over LAN)')),
       
  4124          ] + remoteopts,
       
  4125          _('[OPTION]... SOURCE [DEST]')),
       
  4126     "^commit|ci":
       
  4127         (commit,
       
  4128          [('A', 'addremove', None,
       
  4129            _('mark new/missing files as added/removed before committing')),
       
  4130           ('', 'close-branch', None,
       
  4131            _('mark a branch as closed, hiding it from the branch list')),
       
  4132          ] + walkopts + commitopts + commitopts2,
       
  4133          _('[OPTION]... [FILE]...')),
       
  4134     "copy|cp":
       
  4135         (copy,
       
  4136          [('A', 'after', None, _('record a copy that has already occurred')),
       
  4137           ('f', 'force', None,
       
  4138            _('forcibly copy over an existing managed file')),
       
  4139          ] + walkopts + dryrunopts,
       
  4140          _('[OPTION]... [SOURCE]... DEST')),
       
  4141     "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
       
  4142     "debugbuilddag":
       
  4143         (debugbuilddag,
       
  4144          [('m', 'mergeable-file', None, _('add single file mergeable changes')),
       
  4145           ('a', 'appended-file', None, _('add single file all revs append to')),
       
  4146           ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
       
  4147           ('n', 'new-file', None, _('add new file at each rev')),
       
  4148          ],
       
  4149          _('[OPTION]... TEXT')),
       
  4150     "debugcheckstate": (debugcheckstate, [], ''),
       
  4151     "debugcommands": (debugcommands, [], _('[COMMAND]')),
       
  4152     "debugcomplete":
       
  4153         (debugcomplete,
       
  4154          [('o', 'options', None, _('show the command options'))],
       
  4155          _('[-o] CMD')),
       
  4156     "debugdag":
       
  4157         (debugdag,
       
  4158          [('t', 'tags', None, _('use tags as labels')),
       
  4159           ('b', 'branches', None, _('annotate with branch names')),
       
  4160           ('', 'dots', None, _('use dots for runs')),
       
  4161           ('s', 'spaces', None, _('separate elements by spaces')),
       
  4162          ],
       
  4163          _('[OPTION]... [FILE [REV]...]')),
       
  4164     "debugdate":
       
  4165         (debugdate,
       
  4166          [('e', 'extended', None, _('try extended date formats'))],
       
  4167          _('[-e] DATE [RANGE]')),
       
  4168     "debugdata": (debugdata, [], _('FILE REV')),
       
  4169     "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
       
  4170     "debugindex": (debugindex,
       
  4171                    [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
       
  4172                    _('FILE')),
       
  4173     "debugindexdot": (debugindexdot, [], _('FILE')),
       
  4174     "debuginstall": (debuginstall, [], ''),
       
  4175     "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
       
  4176     "debugrebuildstate":
       
  4177         (debugrebuildstate,
       
  4178          [('r', 'rev', '',
       
  4179            _('revision to rebuild to'), _('REV'))],
       
  4180          _('[-r REV] [REV]')),
       
  4181     "debugrename":
       
  4182         (debugrename,
       
  4183          [('r', 'rev', '',
       
  4184            _('revision to debug'), _('REV'))],
       
  4185          _('[-r REV] FILE')),
       
  4186     "debugrevspec":
       
  4187         (debugrevspec, [], ('REVSPEC')),
       
  4188     "debugsetparents":
       
  4189         (debugsetparents, [], _('REV1 [REV2]')),
       
  4190     "debugstate":
       
  4191         (debugstate,
       
  4192          [('', 'nodates', None, _('do not display the saved mtime'))],
       
  4193          _('[OPTION]...')),
       
  4194     "debugsub":
       
  4195         (debugsub,
       
  4196          [('r', 'rev', '',
       
  4197            _('revision to check'), _('REV'))],
       
  4198          _('[-r REV] [REV]')),
       
  4199     "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
       
  4200     "^diff":
       
  4201         (diff,
       
  4202          [('r', 'rev', [],
       
  4203            _('revision'), _('REV')),
       
  4204           ('c', 'change', '',
       
  4205            _('change made by revision'), _('REV'))
       
  4206          ] + diffopts + diffopts2 + walkopts + subrepoopts,
       
  4207          _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
       
  4208     "^export":
       
  4209         (export,
       
  4210          [('o', 'output', '',
       
  4211            _('print output to file with formatted name'), _('FORMAT')),
       
  4212           ('', 'switch-parent', None, _('diff against the second parent')),
       
  4213           ('r', 'rev', [],
       
  4214            _('revisions to export'), _('REV')),
       
  4215           ] + diffopts,
       
  4216          _('[OPTION]... [-o OUTFILESPEC] REV...')),
       
  4217     "^forget":
       
  4218         (forget,
       
  4219          [] + walkopts,
       
  4220          _('[OPTION]... FILE...')),
       
  4221     "grep":
       
  4222         (grep,
       
  4223          [('0', 'print0', None, _('end fields with NUL')),
       
  4224           ('', 'all', None, _('print all revisions that match')),
       
  4225           ('f', 'follow', None,
       
  4226            _('follow changeset history,'
       
  4227              ' or file history across copies and renames')),
       
  4228           ('i', 'ignore-case', None, _('ignore case when matching')),
       
  4229           ('l', 'files-with-matches', None,
       
  4230            _('print only filenames and revisions that match')),
       
  4231           ('n', 'line-number', None, _('print matching line numbers')),
       
  4232           ('r', 'rev', [],
       
  4233            _('only search files changed within revision range'), _('REV')),
       
  4234           ('u', 'user', None, _('list the author (long with -v)')),
       
  4235           ('d', 'date', None, _('list the date (short with -q)')),
       
  4236          ] + walkopts,
       
  4237          _('[OPTION]... PATTERN [FILE]...')),
       
  4238     "heads":
       
  4239         (heads,
       
  4240          [('r', 'rev', '',
       
  4241            _('show only heads which are descendants of STARTREV'),
       
  4242            _('STARTREV')),
       
  4243           ('t', 'topo', False, _('show topological heads only')),
       
  4244           ('a', 'active', False,
       
  4245            _('show active branchheads only (DEPRECATED)')),
       
  4246           ('c', 'closed', False,
       
  4247            _('show normal and closed branch heads')),
       
  4248          ] + templateopts,
       
  4249          _('[-ac] [-r STARTREV] [REV]...')),
       
  4250     "help": (help_, [], _('[TOPIC]')),
       
  4251     "identify|id":
       
  4252         (identify,
       
  4253          [('r', 'rev', '',
       
  4254            _('identify the specified revision'), _('REV')),
       
  4255           ('n', 'num', None, _('show local revision number')),
       
  4256           ('i', 'id', None, _('show global revision id')),
       
  4257           ('b', 'branch', None, _('show branch')),
       
  4258           ('t', 'tags', None, _('show tags'))],
       
  4259          _('[-nibt] [-r REV] [SOURCE]')),
       
  4260     "import|patch":
       
  4261         (import_,
       
  4262          [('p', 'strip', 1,
       
  4263            _('directory strip option for patch. This has the same '
       
  4264              'meaning as the corresponding patch option'),
       
  4265            _('NUM')),
       
  4266           ('b', 'base', '',
       
  4267            _('base path'), _('PATH')),
       
  4268           ('f', 'force', None,
       
  4269            _('skip check for outstanding uncommitted changes')),
       
  4270           ('', 'no-commit', None,
       
  4271            _("don't commit, just update the working directory")),
       
  4272           ('', 'exact', None,
       
  4273            _('apply patch to the nodes from which it was generated')),
       
  4274           ('', 'import-branch', None,
       
  4275            _('use any branch information in patch (implied by --exact)'))] +
       
  4276          commitopts + commitopts2 + similarityopts,
       
  4277          _('[OPTION]... PATCH...')),
       
  4278     "incoming|in":
       
  4279         (incoming,
       
  4280          [('f', 'force', None,
       
  4281            _('run even if remote repository is unrelated')),
       
  4282           ('n', 'newest-first', None, _('show newest record first')),
       
  4283           ('', 'bundle', '',
       
  4284            _('file to store the bundles into'), _('FILE')),
       
  4285           ('r', 'rev', [],
       
  4286            _('a remote changeset intended to be added'), _('REV')),
       
  4287           ('b', 'branch', [],
       
  4288            _('a specific branch you would like to pull'), _('BRANCH')),
       
  4289          ] + logopts + remoteopts + subrepoopts,
       
  4290          _('[-p] [-n] [-M] [-f] [-r REV]...'
       
  4291            ' [--bundle FILENAME] [SOURCE]')),
       
  4292     "^init":
       
  4293         (init,
       
  4294          remoteopts,
       
  4295          _('[-e CMD] [--remotecmd CMD] [DEST]')),
       
  4296     "locate":
       
  4297         (locate,
       
  4298          [('r', 'rev', '',
       
  4299            _('search the repository as it is in REV'), _('REV')),
       
  4300           ('0', 'print0', None,
       
  4301            _('end filenames with NUL, for use with xargs')),
       
  4302           ('f', 'fullpath', None,
       
  4303            _('print complete paths from the filesystem root')),
       
  4304          ] + walkopts,
       
  4305          _('[OPTION]... [PATTERN]...')),
       
  4306     "^log|history":
       
  4307         (log,
       
  4308          [('f', 'follow', None,
       
  4309            _('follow changeset history,'
       
  4310              ' or file history across copies and renames')),
       
  4311           ('', 'follow-first', None,
       
  4312            _('only follow the first parent of merge changesets')),
       
  4313           ('d', 'date', '',
       
  4314            _('show revisions matching date spec'), _('DATE')),
       
  4315           ('C', 'copies', None, _('show copied files')),
       
  4316           ('k', 'keyword', [],
       
  4317            _('do case-insensitive search for a given text'), _('TEXT')),
       
  4318           ('r', 'rev', [],
       
  4319            _('show the specified revision or range'), _('REV')),
       
  4320           ('', 'removed', None, _('include revisions where files were removed')),
       
  4321           ('m', 'only-merges', None, _('show only merges')),
       
  4322           ('u', 'user', [],
       
  4323            _('revisions committed by user'), _('USER')),
       
  4324           ('', 'only-branch', [],
       
  4325            _('show only changesets within the given named branch (DEPRECATED)'),
       
  4326            _('BRANCH')),
       
  4327           ('b', 'branch', [],
       
  4328            _('show changesets within the given named branch'), _('BRANCH')),
       
  4329           ('P', 'prune', [],
       
  4330            _('do not display revision or any of its ancestors'), _('REV')),
       
  4331          ] + logopts + walkopts,
       
  4332          _('[OPTION]... [FILE]')),
       
  4333     "manifest":
       
  4334         (manifest,
       
  4335          [('r', 'rev', '',
       
  4336            _('revision to display'), _('REV'))],
       
  4337          _('[-r REV]')),
       
  4338     "^merge":
       
  4339         (merge,
       
  4340          [('f', 'force', None, _('force a merge with outstanding changes')),
       
  4341           ('t', 'tool', '', _('specify merge tool')),
       
  4342           ('r', 'rev', '',
       
  4343            _('revision to merge'), _('REV')),
       
  4344           ('P', 'preview', None,
       
  4345            _('review revisions to merge (no merge is performed)'))],
       
  4346          _('[-P] [-f] [[-r] REV]')),
       
  4347     "outgoing|out":
       
  4348         (outgoing,
       
  4349          [('f', 'force', None,
       
  4350            _('run even when the destination is unrelated')),
       
  4351           ('r', 'rev', [],
       
  4352            _('a changeset intended to be included in the destination'),
       
  4353            _('REV')),
       
  4354           ('n', 'newest-first', None, _('show newest record first')),
       
  4355           ('b', 'branch', [],
       
  4356            _('a specific branch you would like to push'), _('BRANCH')),
       
  4357          ] + logopts + remoteopts + subrepoopts,
       
  4358          _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
       
  4359     "parents":
       
  4360         (parents,
       
  4361          [('r', 'rev', '',
       
  4362            _('show parents of the specified revision'), _('REV')),
       
  4363          ] + templateopts,
       
  4364          _('[-r REV] [FILE]')),
       
  4365     "paths": (paths, [], _('[NAME]')),
       
  4366     "^pull":
       
  4367         (pull,
       
  4368          [('u', 'update', None,
       
  4369            _('update to new branch head if changesets were pulled')),
       
  4370           ('f', 'force', None,
       
  4371            _('run even when remote repository is unrelated')),
       
  4372           ('r', 'rev', [],
       
  4373            _('a remote changeset intended to be added'), _('REV')),
       
  4374           ('b', 'branch', [],
       
  4375            _('a specific branch you would like to pull'), _('BRANCH')),
       
  4376          ] + remoteopts,
       
  4377          _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
       
  4378     "^push":
       
  4379         (push,
       
  4380          [('f', 'force', None, _('force push')),
       
  4381           ('r', 'rev', [],
       
  4382            _('a changeset intended to be included in the destination'),
       
  4383            _('REV')),
       
  4384           ('b', 'branch', [],
       
  4385            _('a specific branch you would like to push'), _('BRANCH')),
       
  4386           ('', 'new-branch', False, _('allow pushing a new branch')),
       
  4387          ] + remoteopts,
       
  4388          _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
       
  4389     "recover": (recover, []),
       
  4390     "^remove|rm":
       
  4391         (remove,
       
  4392          [('A', 'after', None, _('record delete for missing files')),
       
  4393           ('f', 'force', None,
       
  4394            _('remove (and delete) file even if added or modified')),
       
  4395          ] + walkopts,
       
  4396          _('[OPTION]... FILE...')),
       
  4397     "rename|move|mv":
       
  4398         (rename,
       
  4399          [('A', 'after', None, _('record a rename that has already occurred')),
       
  4400           ('f', 'force', None,
       
  4401            _('forcibly copy over an existing managed file')),
       
  4402          ] + walkopts + dryrunopts,
       
  4403          _('[OPTION]... SOURCE... DEST')),
       
  4404     "resolve":
       
  4405         (resolve,
       
  4406          [('a', 'all', None, _('select all unresolved files')),
       
  4407           ('l', 'list', None, _('list state of files needing merge')),
       
  4408           ('m', 'mark', None, _('mark files as resolved')),
       
  4409           ('u', 'unmark', None, _('mark files as unresolved')),
       
  4410           ('t', 'tool', '', _('specify merge tool')),
       
  4411           ('n', 'no-status', None, _('hide status prefix'))]
       
  4412           + walkopts,
       
  4413           _('[OPTION]... [FILE]...')),
       
  4414     "revert":
       
  4415         (revert,
       
  4416          [('a', 'all', None, _('revert all changes when no arguments given')),
       
  4417           ('d', 'date', '',
       
  4418            _('tipmost revision matching date'), _('DATE')),
       
  4419           ('r', 'rev', '',
       
  4420            _('revert to the specified revision'), _('REV')),
       
  4421           ('', 'no-backup', None, _('do not save backup copies of files')),
       
  4422          ] + walkopts + dryrunopts,
       
  4423          _('[OPTION]... [-r REV] [NAME]...')),
       
  4424     "rollback": (rollback, dryrunopts),
       
  4425     "root": (root, []),
       
  4426     "^serve":
       
  4427         (serve,
       
  4428          [('A', 'accesslog', '',
       
  4429            _('name of access log file to write to'), _('FILE')),
       
  4430           ('d', 'daemon', None, _('run server in background')),
       
  4431           ('', 'daemon-pipefds', '',
       
  4432            _('used internally by daemon mode'), _('NUM')),
       
  4433           ('E', 'errorlog', '',
       
  4434            _('name of error log file to write to'), _('FILE')),
       
  4435           # use string type, then we can check if something was passed
       
  4436           ('p', 'port', '',
       
  4437            _('port to listen on (default: 8000)'), _('PORT')),
       
  4438           ('a', 'address', '',
       
  4439            _('address to listen on (default: all interfaces)'), _('ADDR')),
       
  4440           ('', 'prefix', '',
       
  4441            _('prefix path to serve from (default: server root)'), _('PREFIX')),
       
  4442           ('n', 'name', '',
       
  4443            _('name to show in web pages (default: working directory)'),
       
  4444            _('NAME')),
       
  4445           ('', 'web-conf', '',
       
  4446            _('name of the hgweb config file (see "hg help hgweb")'),
       
  4447            _('FILE')),
       
  4448           ('', 'webdir-conf', '',
       
  4449            _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
       
  4450           ('', 'pid-file', '',
       
  4451            _('name of file to write process ID to'), _('FILE')),
       
  4452           ('', 'stdio', None, _('for remote clients')),
       
  4453           ('t', 'templates', '',
       
  4454            _('web templates to use'), _('TEMPLATE')),
       
  4455           ('', 'style', '',
       
  4456            _('template style to use'), _('STYLE')),
       
  4457           ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
       
  4458           ('', 'certificate', '',
       
  4459            _('SSL certificate file'), _('FILE'))],
       
  4460          _('[OPTION]...')),
       
  4461     "showconfig|debugconfig":
       
  4462         (showconfig,
       
  4463          [('u', 'untrusted', None, _('show untrusted configuration options'))],
       
  4464          _('[-u] [NAME]...')),
       
  4465     "^summary|sum":
       
  4466         (summary,
       
  4467          [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
       
  4468     "^status|st":
       
  4469         (status,
       
  4470          [('A', 'all', None, _('show status of all files')),
       
  4471           ('m', 'modified', None, _('show only modified files')),
       
  4472           ('a', 'added', None, _('show only added files')),
       
  4473           ('r', 'removed', None, _('show only removed files')),
       
  4474           ('d', 'deleted', None, _('show only deleted (but tracked) files')),
       
  4475           ('c', 'clean', None, _('show only files without changes')),
       
  4476           ('u', 'unknown', None, _('show only unknown (not tracked) files')),
       
  4477           ('i', 'ignored', None, _('show only ignored files')),
       
  4478           ('n', 'no-status', None, _('hide status prefix')),
       
  4479           ('C', 'copies', None, _('show source of copied files')),
       
  4480           ('0', 'print0', None,
       
  4481            _('end filenames with NUL, for use with xargs')),
       
  4482           ('', 'rev', [],
       
  4483            _('show difference from revision'), _('REV')),
       
  4484           ('', 'change', '',
       
  4485            _('list the changed files of a revision'), _('REV')),
       
  4486          ] + walkopts + subrepoopts,
       
  4487          _('[OPTION]... [FILE]...')),
       
  4488     "tag":
       
  4489         (tag,
       
  4490          [('f', 'force', None, _('force tag')),
       
  4491           ('l', 'local', None, _('make the tag local')),
       
  4492           ('r', 'rev', '',
       
  4493            _('revision to tag'), _('REV')),
       
  4494           ('', 'remove', None, _('remove a tag')),
       
  4495           # -l/--local is already there, commitopts cannot be used
       
  4496           ('e', 'edit', None, _('edit commit message')),
       
  4497           ('m', 'message', '',
       
  4498            _('use <text> as commit message'), _('TEXT')),
       
  4499          ] + commitopts2,
       
  4500          _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
       
  4501     "tags": (tags, [], ''),
       
  4502     "tip":
       
  4503         (tip,
       
  4504          [('p', 'patch', None, _('show patch')),
       
  4505           ('g', 'git', None, _('use git extended diff format')),
       
  4506          ] + templateopts,
       
  4507          _('[-p] [-g]')),
       
  4508     "unbundle":
       
  4509         (unbundle,
       
  4510          [('u', 'update', None,
       
  4511            _('update to new branch head if changesets were unbundled'))],
       
  4512          _('[-u] FILE...')),
       
  4513     "^update|up|checkout|co":
       
  4514         (update,
       
  4515          [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
       
  4516           ('c', 'check', None,
       
  4517            _('update across branches if no uncommitted changes')),
       
  4518           ('d', 'date', '',
       
  4519            _('tipmost revision matching date'), _('DATE')),
       
  4520           ('r', 'rev', '',
       
  4521            _('revision'), _('REV'))],
       
  4522          _('[-c] [-C] [-d DATE] [[-r] REV]')),
       
  4523     "verify": (verify, []),
       
  4524     "version": (version_, []),
       
  4525 }
       
  4526 
       
  4527 norepo = ("clone init version help debugcommands debugcomplete"
       
  4528           " debugdate debuginstall debugfsinfo debugpushkey")
       
  4529 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
       
  4530                 " debugdata debugindex debugindexdot")