mercurial/commands.py
changeset 5124 06154aff2b1a
parent 5123 f94dbc6c7eaf
parent 5122 c80af96943aa
child 5138 13d23d66a6cd
equal deleted inserted replaced
5123:f94dbc6c7eaf 5124:06154aff2b1a
     6 # of the GNU General Public License, incorporated herein by reference.
     6 # of the GNU General Public License, incorporated herein by reference.
     7 
     7 
     8 import demandimport; demandimport.enable()
     8 import demandimport; demandimport.enable()
     9 from node import *
     9 from node import *
    10 from i18n import _
    10 from i18n import _
    11 import bisect, os, re, sys, urllib, shlex, stat
    11 import os, re, sys, urllib
    12 import ui, hg, util, revlog, bundlerepo, extensions
    12 import ui, hg, util, revlog, bundlerepo, extensions
    13 import difflib, patch, time, help, mdiff, tempfile
    13 import difflib, patch, time, help, mdiff, tempfile
    14 import errno, version, socket
    14 import errno, version, socket
    15 import archival, changegroup, cmdutil, hgweb.server, sshserver
    15 import archival, changegroup, cmdutil, hgweb.server, sshserver
    16 
    16 
    31     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
    31     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts):
    32         if exact:
    32         if exact:
    33             if ui.verbose:
    33             if ui.verbose:
    34                 ui.status(_('adding %s\n') % rel)
    34                 ui.status(_('adding %s\n') % rel)
    35             names.append(abs)
    35             names.append(abs)
    36         elif repo.dirstate.state(abs) == '?':
    36         elif abs not in repo.dirstate:
    37             ui.status(_('adding %s\n') % rel)
    37             ui.status(_('adding %s\n') % rel)
    38             names.append(abs)
    38             names.append(abs)
    39     if not opts.get('dry_run'):
    39     if not opts.get('dry_run'):
    40         repo.add(names)
    40         repo.add(names)
    41 
    41 
    71 
    71 
    72     Without the -a option, annotate will avoid processing files it
    72     Without the -a option, annotate will avoid processing files it
    73     detects as binary. With -a, annotate will generate an annotation
    73     detects as binary. With -a, annotate will generate an annotation
    74     anyway, probably with undesirable results.
    74     anyway, probably with undesirable results.
    75     """
    75     """
    76     getdate = util.cachefunc(lambda x: util.datestr(x.date()))
    76     getdate = util.cachefunc(lambda x: util.datestr(x[0].date()))
    77 
    77 
    78     if not pats:
    78     if not pats:
    79         raise util.Abort(_('at least one file name or pattern required'))
    79         raise util.Abort(_('at least one file name or pattern required'))
    80 
    80 
    81     opmap = [['user', lambda x: ui.shortuser(x.user())],
    81     opmap = [('user', lambda x: ui.shortuser(x[0].user())),
    82              ['number', lambda x: str(x.rev())],
    82              ('number', lambda x: str(x[0].rev())),
    83              ['changeset', lambda x: short(x.node())],
    83              ('changeset', lambda x: short(x[0].node())),
    84              ['date', getdate], ['follow', lambda x: x.path()]]
    84              ('date', getdate),
       
    85              ('follow', lambda x: x[0].path()),
       
    86             ]
       
    87 
    85     if (not opts['user'] and not opts['changeset'] and not opts['date']
    88     if (not opts['user'] and not opts['changeset'] and not opts['date']
    86         and not opts['follow']):
    89         and not opts['follow']):
    87         opts['number'] = 1
    90         opts['number'] = 1
       
    91 
       
    92     linenumber = opts.get('line_number') is not None
       
    93     if (linenumber and (not opts['changeset']) and (not opts['number'])):
       
    94         raise util.Abort(_('at least one of -n/-c is required for -l'))
       
    95 
       
    96     funcmap = [func for op, func in opmap if opts.get(op)]
       
    97     if linenumber:
       
    98         lastfunc = funcmap[-1]
       
    99         funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
    88 
   100 
    89     ctx = repo.changectx(opts['rev'])
   101     ctx = repo.changectx(opts['rev'])
    90 
   102 
    91     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
   103     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
    92                                              node=ctx.node()):
   104                                              node=ctx.node()):
    93         fctx = ctx.filectx(abs)
   105         fctx = ctx.filectx(abs)
    94         if not opts['text'] and util.binary(fctx.data()):
   106         if not opts['text'] and util.binary(fctx.data()):
    95             ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
   107             ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
    96             continue
   108             continue
    97 
   109 
    98         lines = fctx.annotate(follow=opts.get('follow'))
   110         lines = fctx.annotate(follow=opts.get('follow'),
       
   111                               linenumber=linenumber)
    99         pieces = []
   112         pieces = []
   100 
   113 
   101         for o, f in opmap:
   114         for f in funcmap:
   102             if opts[o]:
   115             l = [f(n) for n, dummy in lines]
   103                 l = [f(n) for n, dummy in lines]
   116             if l:
   104                 if l:
   117                 m = max(map(len, l))
   105                     m = max(map(len, l))
   118                 pieces.append(["%*s" % (m, x) for x in l])
   106                     pieces.append(["%*s" % (m, x) for x in l])
       
   107 
   119 
   108         if pieces:
   120         if pieces:
   109             for p, l in zip(zip(*pieces), lines):
   121             for p, l in zip(zip(*pieces), lines):
   110                 ui.write("%s: %s" % (" ".join(p), l[1]))
   122                 ui.write("%s: %s" % (" ".join(p), l[1]))
   111 
   123 
   414     will be committed.
   426     will be committed.
   415 
   427 
   416     If no commit message is specified, the editor configured in your hgrc
   428     If no commit message is specified, the editor configured in your hgrc
   417     or in the EDITOR environment variable is started to enter a message.
   429     or in the EDITOR environment variable is started to enter a message.
   418     """
   430     """
   419     message = cmdutil.logmessage(opts)
   431     def commitfunc(ui, repo, files, message, match, opts):
   420 
   432         return repo.commit(files, message, opts['user'], opts['date'], match,
   421     if opts['addremove']:
   433                            force_editor=opts.get('force_editor'))
   422         cmdutil.addremove(repo, pats, opts)
   434     cmdutil.commit(ui, repo, commitfunc, pats, opts)
   423     fns, match, anypats = cmdutil.matchpats(repo, pats, opts)
   435 
   424     if pats:
   436 def docopy(ui, repo, pats, opts):
   425         status = repo.status(files=fns, match=match)
       
   426         modified, added, removed, deleted, unknown = status[:5]
       
   427         files = modified + added + removed
       
   428         slist = None
       
   429         for f in fns:
       
   430             if f == '.':
       
   431                 continue
       
   432             if f not in files:
       
   433                 rf = repo.wjoin(f)
       
   434                 try:
       
   435                     mode = os.lstat(rf)[stat.ST_MODE]
       
   436                 except OSError:
       
   437                     raise util.Abort(_("file %s not found!") % rf)
       
   438                 if stat.S_ISDIR(mode):
       
   439                     name = f + '/'
       
   440                     if slist is None:
       
   441                         slist = list(files)
       
   442                         slist.sort()
       
   443                     i = bisect.bisect(slist, name)
       
   444                     if i >= len(slist) or not slist[i].startswith(name):
       
   445                         raise util.Abort(_("no match under directory %s!")
       
   446                                          % rf)
       
   447                 elif not (stat.S_ISREG(mode) or stat.S_ISLNK(mode)):
       
   448                     raise util.Abort(_("can't commit %s: "
       
   449                                        "unsupported file type!") % rf)
       
   450                 elif repo.dirstate.state(f) == '?':
       
   451                     raise util.Abort(_("file %s not tracked!") % rf)
       
   452     else:
       
   453         files = []
       
   454     try:
       
   455         repo.commit(files, message, opts['user'], opts['date'], match,
       
   456                     force_editor=opts.get('force_editor'))
       
   457     except ValueError, inst:
       
   458         raise util.Abort(str(inst))
       
   459 
       
   460 def docopy(ui, repo, pats, opts, wlock):
       
   461     # called with the repo lock held
   437     # called with the repo lock held
   462     #
   438     #
   463     # hgsep => pathname that uses "/" to separate directories
   439     # hgsep => pathname that uses "/" to separate directories
   464     # ossep => pathname that uses os.sep to separate directories
   440     # ossep => pathname that uses os.sep to separate directories
   465     cwd = repo.getcwd()
   441     cwd = repo.getcwd()
   471     # rel: ossep
   447     # rel: ossep
   472     # return: hgsep
   448     # return: hgsep
   473     def okaytocopy(abs, rel, exact):
   449     def okaytocopy(abs, rel, exact):
   474         reasons = {'?': _('is not managed'),
   450         reasons = {'?': _('is not managed'),
   475                    'r': _('has been marked for remove')}
   451                    'r': _('has been marked for remove')}
   476         state = repo.dirstate.state(abs)
   452         state = repo.dirstate[abs]
   477         reason = reasons.get(state)
   453         reason = reasons.get(state)
   478         if reason:
   454         if reason:
   479             if exact:
   455             if exact:
   480                 ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
   456                 ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
   481         else:
   457         else:
   499             ui.warn(_('%s: not overwriting - %s collides with %s\n') %
   475             ui.warn(_('%s: not overwriting - %s collides with %s\n') %
   500                     (reltarget, repo.pathto(abssrc, cwd),
   476                     (reltarget, repo.pathto(abssrc, cwd),
   501                      repo.pathto(prevsrc, cwd)))
   477                      repo.pathto(prevsrc, cwd)))
   502             return
   478             return
   503         if (not opts['after'] and os.path.exists(target) or
   479         if (not opts['after'] and os.path.exists(target) or
   504             opts['after'] and repo.dirstate.state(abstarget) not in '?ar'):
   480             opts['after'] and repo.dirstate[abstarget] in 'mn'):
   505             if not opts['force']:
   481             if not opts['force']:
   506                 ui.warn(_('%s: not overwriting - file exists\n') %
   482                 ui.warn(_('%s: not overwriting - file exists\n') %
   507                         reltarget)
   483                         reltarget)
   508                 return
   484                 return
   509             if not opts['after'] and not opts.get('dry_run'):
   485             if not opts['after'] and not opts.get('dry_run'):
   514         else:
   490         else:
   515             targetdir = os.path.dirname(target) or '.'
   491             targetdir = os.path.dirname(target) or '.'
   516             if not os.path.isdir(targetdir) and not opts.get('dry_run'):
   492             if not os.path.isdir(targetdir) and not opts.get('dry_run'):
   517                 os.makedirs(targetdir)
   493                 os.makedirs(targetdir)
   518             try:
   494             try:
   519                 restore = repo.dirstate.state(abstarget) == 'r'
   495                 restore = repo.dirstate[abstarget] == 'r'
   520                 if restore and not opts.get('dry_run'):
   496                 if restore and not opts.get('dry_run'):
   521                     repo.undelete([abstarget], wlock)
   497                     repo.undelete([abstarget])
   522                 try:
   498                 try:
   523                     if not opts.get('dry_run'):
   499                     if not opts.get('dry_run'):
   524                         util.copyfile(src, target)
   500                         util.copyfile(src, target)
   525                     restore = False
   501                     restore = False
   526                 finally:
   502                 finally:
   527                     if restore:
   503                     if restore:
   528                         repo.remove([abstarget], wlock=wlock)
   504                         repo.remove([abstarget])
   529             except IOError, inst:
   505             except IOError, inst:
   530                 if inst.errno == errno.ENOENT:
   506                 if inst.errno == errno.ENOENT:
   531                     ui.warn(_('%s: deleted in working copy\n') % relsrc)
   507                     ui.warn(_('%s: deleted in working copy\n') % relsrc)
   532                 else:
   508                 else:
   533                     ui.warn(_('%s: cannot copy - %s\n') %
   509                     ui.warn(_('%s: cannot copy - %s\n') %
   536                     return
   512                     return
   537         if ui.verbose or not exact:
   513         if ui.verbose or not exact:
   538             ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
   514             ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
   539         targets[abstarget] = abssrc
   515         targets[abstarget] = abssrc
   540         if abstarget != origsrc:
   516         if abstarget != origsrc:
   541             if repo.dirstate.state(origsrc) == 'a':
   517             if repo.dirstate[origsrc] == 'a':
   542                 if not ui.quiet:
   518                 if not ui.quiet:
   543                     ui.warn(_("%s has not been committed yet, so no copy "
   519                     ui.warn(_("%s has not been committed yet, so no copy "
   544                               "data will be stored for %s.\n")
   520                               "data will be stored for %s.\n")
   545                             % (repo.pathto(origsrc, cwd), reltarget))
   521                             % (repo.pathto(origsrc, cwd), reltarget))
   546                 if abstarget not in repo.dirstate and not opts.get('dry_run'):
   522                 if abstarget not in repo.dirstate and not opts.get('dry_run'):
   547                     repo.add([abstarget], wlock)
   523                     repo.add([abstarget])
   548             elif not opts.get('dry_run'):
   524             elif not opts.get('dry_run'):
   549                 repo.copy(origsrc, abstarget, wlock)
   525                 repo.copy(origsrc, abstarget)
   550         copied.append((abssrc, relsrc, exact))
   526         copied.append((abssrc, relsrc, exact))
   551 
   527 
   552     # pat: ossep
   528     # pat: ossep
   553     # dest ossep
   529     # dest ossep
   554     # srcs: list of (hgsep, hgsep, ossep, bool)
   530     # srcs: list of (hgsep, hgsep, ossep, bool)
   664     operation is recorded, but no copying is performed.
   640     operation is recorded, but no copying is performed.
   665 
   641 
   666     This command takes effect in the next commit. To undo a copy
   642     This command takes effect in the next commit. To undo a copy
   667     before that, see hg revert.
   643     before that, see hg revert.
   668     """
   644     """
   669     wlock = repo.wlock(0)
   645     wlock = repo.wlock(False)
   670     errs, copied = docopy(ui, repo, pats, opts, wlock)
   646     try:
       
   647         errs, copied = docopy(ui, repo, pats, opts)
       
   648     finally:
       
   649         del wlock
   671     return errs
   650     return errs
   672 
   651 
   673 def debugancestor(ui, index, rev1, rev2):
   652 def debugancestor(ui, index, rev1, rev2):
   674     """find the ancestor revision of two revisions in a given index"""
   653     """find the ancestor revision of two revisions in a given index"""
   675     r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
   654     r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
   702     if rev == "":
   681     if rev == "":
   703         rev = repo.changelog.tip()
   682         rev = repo.changelog.tip()
   704     ctx = repo.changectx(rev)
   683     ctx = repo.changectx(rev)
   705     files = ctx.manifest()
   684     files = ctx.manifest()
   706     wlock = repo.wlock()
   685     wlock = repo.wlock()
   707     repo.dirstate.rebuild(rev, files)
   686     try:
       
   687         repo.dirstate.rebuild(rev, files)
       
   688     finally:
       
   689         del wlock
   708 
   690 
   709 def debugcheckstate(ui, repo):
   691 def debugcheckstate(ui, repo):
   710     """validate the correctness of the current dirstate"""
   692     """validate the correctness of the current dirstate"""
   711     parent1, parent2 = repo.dirstate.parents()
   693     parent1, parent2 = repo.dirstate.parents()
   712     dc = repo.dirstate
       
   713     m1 = repo.changectx(parent1).manifest()
   694     m1 = repo.changectx(parent1).manifest()
   714     m2 = repo.changectx(parent2).manifest()
   695     m2 = repo.changectx(parent2).manifest()
   715     errors = 0
   696     errors = 0
   716     for f in dc:
   697     for f in repo.dirstate:
   717         state = repo.dirstate.state(f)
   698         state = repo.dirstate[f]
   718         if state in "nr" and f not in m1:
   699         if state in "nr" and f not in m1:
   719             ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
   700             ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
   720             errors += 1
   701             errors += 1
   721         if state in "a" and f in m1:
   702         if state in "a" and f in m1:
   722             ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
   703             ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
   724         if state in "m" and f not in m1 and f not in m2:
   705         if state in "m" and f not in m1 and f not in m2:
   725             ui.warn(_("%s in state %s, but not in either manifest\n") %
   706             ui.warn(_("%s in state %s, but not in either manifest\n") %
   726                     (f, state))
   707                     (f, state))
   727             errors += 1
   708             errors += 1
   728     for f in m1:
   709     for f in m1:
   729         state = repo.dirstate.state(f)
   710         state = repo.dirstate[f]
   730         if state not in "nrm":
   711         if state not in "nrm":
   731             ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
   712             ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
   732             errors += 1
   713             errors += 1
   733     if errors:
   714     if errors:
   734         error = _(".hg/dirstate inconsistent with current parent's manifest")
   715         error = _(".hg/dirstate inconsistent with current parent's manifest")
   772 
   753 
   773     wlock = repo.wlock()
   754     wlock = repo.wlock()
   774     try:
   755     try:
   775         repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
   756         repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
   776     finally:
   757     finally:
   777         wlock.release()
   758         del wlock
   778 
   759 
   779 def debugstate(ui, repo):
   760 def debugstate(ui, repo):
   780     """show the contents of the current dirstate"""
   761     """show the contents of the current dirstate"""
   781     dc = repo.dirstate
   762     dc = repo.dirstate._map
   782     for file_ in dc:
   763     k = dc.keys()
       
   764     k.sort()
       
   765     for file_ in k:
   783         if dc[file_][3] == -1:
   766         if dc[file_][3] == -1:
   784             # Pad or slice to locale representation
   767             # Pad or slice to locale representation
   785             locale_len = len(time.strftime("%x %X", time.localtime(0)))
   768             locale_len = len(time.strftime("%x %X", time.localtime(0)))
   786             timestr = 'unset'
   769             timestr = 'unset'
   787             timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
   770             timestr = timestr[:locale_len] + ' '*(locale_len - len(timestr))
   839 
   822 
   840 def debuginstall(ui):
   823 def debuginstall(ui):
   841     '''test Mercurial installation'''
   824     '''test Mercurial installation'''
   842 
   825 
   843     def writetemp(contents):
   826     def writetemp(contents):
   844         (fd, name) = tempfile.mkstemp()
   827         (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
   845         f = os.fdopen(fd, "wb")
   828         f = os.fdopen(fd, "wb")
   846         f.write(contents)
   829         f.write(contents)
   847         f.close()
   830         f.close()
   848         return name
   831         return name
   849 
   832 
  1570     if opts.get('exact') or not opts['force']:
  1553     if opts.get('exact') or not opts['force']:
  1571         cmdutil.bail_if_changed(repo)
  1554         cmdutil.bail_if_changed(repo)
  1572 
  1555 
  1573     d = opts["base"]
  1556     d = opts["base"]
  1574     strip = opts["strip"]
  1557     strip = opts["strip"]
  1575 
  1558     wlock = lock = None
  1576     wlock = repo.wlock()
  1559     try:
  1577     lock = repo.lock()
  1560         wlock = repo.wlock()
  1578 
  1561         lock = repo.lock()
  1579     for p in patches:
  1562         for p in patches:
  1580         pf = os.path.join(d, p)
  1563             pf = os.path.join(d, p)
  1581 
  1564 
  1582         if pf == '-':
  1565             if pf == '-':
  1583             ui.status(_("applying patch from stdin\n"))
  1566                 ui.status(_("applying patch from stdin\n"))
  1584             tmpname, message, user, date, branch, nodeid, p1, p2 = patch.extract(ui, sys.stdin)
  1567                 data = patch.extract(ui, sys.stdin)
  1585         else:
       
  1586             ui.status(_("applying %s\n") % p)
       
  1587             tmpname, message, user, date, branch, nodeid, p1, p2 = patch.extract(ui, file(pf, 'rb'))
       
  1588 
       
  1589         if tmpname is None:
       
  1590             raise util.Abort(_('no diffs found'))
       
  1591 
       
  1592         try:
       
  1593             cmdline_message = cmdutil.logmessage(opts)
       
  1594             if cmdline_message:
       
  1595                 # pickup the cmdline msg
       
  1596                 message = cmdline_message
       
  1597             elif message:
       
  1598                 # pickup the patch msg
       
  1599                 message = message.strip()
       
  1600             else:
  1568             else:
  1601                 # launch the editor
  1569                 ui.status(_("applying %s\n") % p)
  1602                 message = None
  1570                 data = patch.extract(ui, file(pf, 'rb'))
  1603             ui.debug(_('message:\n%s\n') % message)
  1571 
  1604 
  1572             tmpname, message, user, date, branch, nodeid, p1, p2 = data
  1605             wp = repo.workingctx().parents()
  1573 
  1606             if opts.get('exact'):
  1574             if tmpname is None:
  1607                 if not nodeid or not p1:
  1575                 raise util.Abort(_('no diffs found'))
  1608                     raise util.Abort(_('not a mercurial patch'))
  1576 
  1609                 p1 = repo.lookup(p1)
  1577             try:
  1610                 p2 = repo.lookup(p2 or hex(nullid))
  1578                 cmdline_message = cmdutil.logmessage(opts)
  1611 
  1579                 if cmdline_message:
  1612                 if p1 != wp[0].node():
  1580                     # pickup the cmdline msg
  1613                     hg.clean(repo, p1, wlock=wlock)
  1581                     message = cmdline_message
  1614                 repo.dirstate.setparents(p1, p2)
  1582                 elif message:
  1615             elif p2:
  1583                     # pickup the patch msg
       
  1584                     message = message.strip()
       
  1585                 else:
       
  1586                     # launch the editor
       
  1587                     message = None
       
  1588                 ui.debug(_('message:\n%s\n') % message)
       
  1589 
       
  1590                 wp = repo.workingctx().parents()
       
  1591                 if opts.get('exact'):
       
  1592                     if not nodeid or not p1:
       
  1593                         raise util.Abort(_('not a mercurial patch'))
       
  1594                     p1 = repo.lookup(p1)
       
  1595                     p2 = repo.lookup(p2 or hex(nullid))
       
  1596 
       
  1597                     if p1 != wp[0].node():
       
  1598                         hg.clean(repo, p1)
       
  1599                     repo.dirstate.setparents(p1, p2)
       
  1600                 elif p2:
       
  1601                     try:
       
  1602                         p1 = repo.lookup(p1)
       
  1603                         p2 = repo.lookup(p2)
       
  1604                         if p1 == wp[0].node():
       
  1605                             repo.dirstate.setparents(p1, p2)
       
  1606                     except hg.RepoError:
       
  1607                         pass
       
  1608                 if opts.get('exact') or opts.get('import_branch'):
       
  1609                     repo.dirstate.setbranch(branch or 'default')
       
  1610 
       
  1611                 files = {}
  1616                 try:
  1612                 try:
  1617                     p1 = repo.lookup(p1)
  1613                     fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
  1618                     p2 = repo.lookup(p2)
  1614                                        files=files)
  1619                     if p1 == wp[0].node():
  1615                 finally:
  1620                         repo.dirstate.setparents(p1, p2)
  1616                     files = patch.updatedir(ui, repo, files)
  1621                 except hg.RepoError:
  1617                 n = repo.commit(files, message, user, date)
  1622                     pass
  1618                 if opts.get('exact'):
  1623             if opts.get('exact') or opts.get('import_branch'):
  1619                     if hex(n) != nodeid:
  1624                 repo.dirstate.setbranch(branch or 'default')
  1620                         repo.rollback()
  1625 
  1621                         raise util.Abort(_('patch is damaged' +
  1626             files = {}
  1622                                            ' or loses information'))
  1627             try:
       
  1628                 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
       
  1629                                    files=files)
       
  1630             finally:
  1623             finally:
  1631                 files = patch.updatedir(ui, repo, files, wlock=wlock)
  1624                 os.unlink(tmpname)
  1632             n = repo.commit(files, message, user, date, wlock=wlock, lock=lock)
  1625     finally:
  1633             if opts.get('exact'):
  1626         del lock, wlock
  1634                 if hex(n) != nodeid:
       
  1635                     repo.rollback(wlock=wlock, lock=lock)
       
  1636                     raise util.Abort(_('patch is damaged or loses information'))
       
  1637         finally:
       
  1638             os.unlink(tmpname)
       
  1639 
  1627 
  1640 def incoming(ui, repo, source="default", **opts):
  1628 def incoming(ui, repo, source="default", **opts):
  1641     """show new changesets found in source
  1629     """show new changesets found in source
  1642 
  1630 
  1643     Show new changesets found in the specified path/URL or the default
  1631     Show new changesets found in the specified path/URL or the default
  1748     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
  1736     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
  1749                                              badmatch=util.always,
  1737                                              badmatch=util.always,
  1750                                              default='relglob'):
  1738                                              default='relglob'):
  1751         if src == 'b':
  1739         if src == 'b':
  1752             continue
  1740             continue
  1753         if not node and repo.dirstate.state(abs) == '?':
  1741         if not node and abs not in repo.dirstate:
  1754             continue
  1742             continue
  1755         if opts['fullpath']:
  1743         if opts['fullpath']:
  1756             ui.write(os.path.join(repo.root, abs), end)
  1744             ui.write(os.path.join(repo.root, abs), end)
  1757         else:
  1745         else:
  1758             ui.write(((pats and rel) or abs), end)
  1746             ui.write(((pats and rel) or abs), end)
  2186     To undo a remove before that, see hg revert.
  2174     To undo a remove before that, see hg revert.
  2187 
  2175 
  2188     Modified files and added files are not removed by default.  To
  2176     Modified files and added files are not removed by default.  To
  2189     remove them, use the -f/--force option.
  2177     remove them, use the -f/--force option.
  2190     """
  2178     """
  2191     names = []
       
  2192     if not opts['after'] and not pats:
  2179     if not opts['after'] and not pats:
  2193         raise util.Abort(_('no files specified'))
  2180         raise util.Abort(_('no files specified'))
  2194     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
  2181     files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts)
  2195     exact = dict.fromkeys(files)
  2182     exact = dict.fromkeys(files)
  2196     mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
  2183     mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5]
  2203         elif abs in added:
  2190         elif abs in added:
  2204             if opts['force']:
  2191             if opts['force']:
  2205                 forget.append(abs)
  2192                 forget.append(abs)
  2206                 continue
  2193                 continue
  2207             reason = _('has been marked for add (use -f to force removal)')
  2194             reason = _('has been marked for add (use -f to force removal)')
  2208         elif repo.dirstate.state(abs) == '?':
  2195         elif abs not in repo.dirstate:
  2209             reason = _('is not managed')
  2196             reason = _('is not managed')
  2210         elif opts['after'] and not exact and abs not in deleted:
  2197         elif opts['after'] and not exact and abs not in deleted:
  2211             continue
  2198             continue
  2212         elif abs in removed:
  2199         elif abs in removed:
  2213             continue
  2200             continue
  2233     operation is recorded, but no copying is performed.
  2220     operation is recorded, but no copying is performed.
  2234 
  2221 
  2235     This command takes effect in the next commit. To undo a rename
  2222     This command takes effect in the next commit. To undo a rename
  2236     before that, see hg revert.
  2223     before that, see hg revert.
  2237     """
  2224     """
  2238     wlock = repo.wlock(0)
  2225     wlock = repo.wlock(False)
  2239     errs, copied = docopy(ui, repo, pats, opts, wlock)
  2226     try:
  2240     names = []
  2227         errs, copied = docopy(ui, repo, pats, opts)
  2241     for abs, rel, exact in copied:
  2228         names = []
  2242         if ui.verbose or not exact:
  2229         for abs, rel, exact in copied:
  2243             ui.status(_('removing %s\n') % rel)
  2230             if ui.verbose or not exact:
  2244         names.append(abs)
  2231                 ui.status(_('removing %s\n') % rel)
  2245     if not opts.get('dry_run'):
  2232             names.append(abs)
  2246         repo.remove(names, True, wlock=wlock)
  2233         if not opts.get('dry_run'):
  2247     return errs
  2234             repo.remove(names, True)
       
  2235         return errs
       
  2236     finally:
       
  2237         del wlock
  2248 
  2238 
  2249 def revert(ui, repo, *pats, **opts):
  2239 def revert(ui, repo, *pats, **opts):
  2250     """revert files or dirs to their states as of some revision
  2240     """revert files or dirs to their states as of some revision
  2251 
  2241 
  2252     With no revision specified, revert the named files or directories
  2242     With no revision specified, revert the named files or directories
  2296     if node == parent:
  2286     if node == parent:
  2297         pmf = mf
  2287         pmf = mf
  2298     else:
  2288     else:
  2299         pmf = None
  2289         pmf = None
  2300 
  2290 
  2301     wlock = repo.wlock()
       
  2302 
       
  2303     # need all matching names in dirstate and manifest of target rev,
  2291     # need all matching names in dirstate and manifest of target rev,
  2304     # so have to walk both. do not print errors if files exist in one
  2292     # so have to walk both. do not print errors if files exist in one
  2305     # but not other.
  2293     # but not other.
  2306 
  2294 
  2307     names = {}
  2295     names = {}
  2308     target_only = {}
  2296     target_only = {}
  2309 
  2297 
  2310     # walk dirstate.
  2298     wlock = repo.wlock()
  2311 
  2299     try:
  2312     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
  2300         # walk dirstate.
  2313                                              badmatch=mf.has_key):
  2301         for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
  2314         names[abs] = (rel, exact)
  2302                                                  badmatch=mf.has_key):
  2315         if src == 'b':
  2303             names[abs] = (rel, exact)
       
  2304             if src == 'b':
       
  2305                 target_only[abs] = True
       
  2306 
       
  2307         # walk target manifest.
       
  2308 
       
  2309         def badmatch(path):
       
  2310             if path in names:
       
  2311                 return True
       
  2312             path_ = path + '/'
       
  2313             for f in names:
       
  2314                 if f.startswith(path_):
       
  2315                     return True
       
  2316             return False
       
  2317 
       
  2318         for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
       
  2319                                                  badmatch=badmatch):
       
  2320             if abs in names or src == 'b':
       
  2321                 continue
       
  2322             names[abs] = (rel, exact)
  2316             target_only[abs] = True
  2323             target_only[abs] = True
  2317 
  2324 
  2318     # walk target manifest.
  2325         changes = repo.status(match=names.has_key)[:5]
  2319 
  2326         modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
  2320     def badmatch(path):
  2327 
  2321         if path in names:
  2328         revert = ([], _('reverting %s\n'))
  2322             return True
  2329         add = ([], _('adding %s\n'))
  2323         path_ = path + '/'
  2330         remove = ([], _('removing %s\n'))
  2324         for f in names:
  2331         forget = ([], _('forgetting %s\n'))
  2325             if f.startswith(path_):
  2332         undelete = ([], _('undeleting %s\n'))
  2326                 return True
  2333         update = {}
  2327         return False
  2334 
  2328 
  2335         disptable = (
  2329     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node,
  2336             # dispatch table:
  2330                                              badmatch=badmatch):
  2337             #   file state
  2331         if abs in names or src == 'b':
  2338             #   action if in target manifest
  2332             continue
  2339             #   action if not in target manifest
  2333         names[abs] = (rel, exact)
  2340             #   make backup if in target manifest
  2334         target_only[abs] = True
  2341             #   make backup if not in target manifest
  2335 
  2342             (modified, revert, remove, True, True),
  2336     changes = repo.status(match=names.has_key, wlock=wlock)[:5]
  2343             (added, revert, forget, True, False),
  2337     modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
  2344             (removed, undelete, None, False, False),
  2338 
  2345             (deleted, revert, remove, False, False),
  2339     revert = ([], _('reverting %s\n'))
  2346             (unknown, add, None, True, False),
  2340     add = ([], _('adding %s\n'))
  2347             (target_only, add, None, False, False),
  2341     remove = ([], _('removing %s\n'))
  2348             )
  2342     forget = ([], _('forgetting %s\n'))
  2349 
  2343     undelete = ([], _('undeleting %s\n'))
  2350         entries = names.items()
  2344     update = {}
  2351         entries.sort()
  2345 
  2352 
  2346     disptable = (
  2353         for abs, (rel, exact) in entries:
  2347         # dispatch table:
  2354             mfentry = mf.get(abs)
  2348         #   file state
  2355             target = repo.wjoin(abs)
  2349         #   action if in target manifest
  2356             def handle(xlist, dobackup):
  2350         #   action if not in target manifest
  2357                 xlist[0].append(abs)
  2351         #   make backup if in target manifest
  2358                 update[abs] = 1
  2352         #   make backup if not in target manifest
  2359                 if dobackup and not opts['no_backup'] and util.lexists(target):
  2353         (modified, revert, remove, True, True),
  2360                     bakname = "%s.orig" % rel
  2354         (added, revert, forget, True, False),
  2361                     ui.note(_('saving current version of %s as %s\n') %
  2355         (removed, undelete, None, False, False),
  2362                             (rel, bakname))
  2356         (deleted, revert, remove, False, False),
  2363                     if not opts.get('dry_run'):
  2357         (unknown, add, None, True, False),
  2364                         util.copyfile(target, bakname)
  2358         (target_only, add, None, False, False),
  2365                 if ui.verbose or not exact:
  2359         )
  2366                     ui.status(xlist[1] % rel)
  2360 
  2367             for table, hitlist, misslist, backuphit, backupmiss in disptable:
  2361     entries = names.items()
  2368                 if abs not in table: continue
  2362     entries.sort()
  2369                 # file has changed in dirstate
  2363 
  2370                 if mfentry:
  2364     for abs, (rel, exact) in entries:
  2371                     handle(hitlist, backuphit)
  2365         mfentry = mf.get(abs)
  2372                 elif misslist is not None:
  2366         target = repo.wjoin(abs)
  2373                     handle(misslist, backupmiss)
  2367         def handle(xlist, dobackup):
  2374                 else:
  2368             xlist[0].append(abs)
  2375                     if exact: ui.warn(_('file not managed: %s\n') % rel)
  2369             update[abs] = 1
  2376                 break
  2370             if dobackup and not opts['no_backup'] and util.lexists(target):
       
  2371                 bakname = "%s.orig" % rel
       
  2372                 ui.note(_('saving current version of %s as %s\n') %
       
  2373                         (rel, bakname))
       
  2374                 if not opts.get('dry_run'):
       
  2375                     util.copyfile(target, bakname)
       
  2376             if ui.verbose or not exact:
       
  2377                 ui.status(xlist[1] % rel)
       
  2378         for table, hitlist, misslist, backuphit, backupmiss in disptable:
       
  2379             if abs not in table: continue
       
  2380             # file has changed in dirstate
       
  2381             if mfentry:
       
  2382                 handle(hitlist, backuphit)
       
  2383             elif misslist is not None:
       
  2384                 handle(misslist, backupmiss)
       
  2385             else:
  2377             else:
  2386                 if exact: ui.warn(_('file not managed: %s\n') % rel)
  2378                 # file has not changed in dirstate
  2387             break
  2379                 if node == parent:
  2388         else:
  2380                     if exact: ui.warn(_('no changes needed to %s\n') % rel)
  2389             # file has not changed in dirstate
  2381                     continue
  2390             if node == parent:
  2382                 if pmf is None:
  2391                 if exact: ui.warn(_('no changes needed to %s\n') % rel)
  2383                     # only need parent manifest in this unlikely case,
  2392                 continue
  2384                     # so do not read by default
  2393             if pmf is None:
  2385                     pmf = repo.changectx(parent).manifest()
  2394                 # only need parent manifest in this unlikely case,
  2386                 if abs in pmf:
  2395                 # so do not read by default
  2387                     if mfentry:
  2396                 pmf = repo.changectx(parent).manifest()
  2388                         # if version of file is same in parent and target
  2397             if abs in pmf:
  2389                         # manifests, do nothing
  2398                 if mfentry:
  2390                         if pmf[abs] != mfentry:
  2399                     # if version of file is same in parent and target
  2391                             handle(revert, False)
  2400                     # manifests, do nothing
  2392                     else:
  2401                     if pmf[abs] != mfentry:
  2393                         handle(remove, False)
  2402                         handle(revert, False)
  2394 
  2403                 else:
  2395         if not opts.get('dry_run'):
  2404                     handle(remove, False)
  2396             for f in forget[0]:
  2405 
  2397                 repo.dirstate.forget(f)
  2406     if not opts.get('dry_run'):
  2398             r = hg.revert(repo, node, update.has_key)
  2407         repo.dirstate.forget(forget[0])
  2399             for f in add[0]:
  2408         r = hg.revert(repo, node, update.has_key, wlock)
  2400                 repo.dirstate.add(f)
  2409         repo.dirstate.update(add[0], 'a')
  2401             for f in undelete[0]:
  2410         repo.dirstate.update(undelete[0], 'n')
  2402                 repo.dirstate.normal(f)
  2411         repo.dirstate.update(remove[0], 'r')
  2403             for f in remove[0]:
  2412         return r
  2404                 repo.dirstate.remove(f)
       
  2405             return r
       
  2406     finally:
       
  2407         del wlock
  2413 
  2408 
  2414 def rollback(ui, repo):
  2409 def rollback(ui, repo):
  2415     """roll back the last transaction in this repository
  2410     """roll back the last transaction in this repository
  2416 
  2411 
  2417     Roll back the last transaction in this repository, restoring the
  2412     Roll back the last transaction in this repository, restoring the
  2465         s = sshserver.sshserver(ui, repo)
  2460         s = sshserver.sshserver(ui, repo)
  2466         s.serve_forever()
  2461         s.serve_forever()
  2467 
  2462 
  2468     parentui = ui.parentui or ui
  2463     parentui = ui.parentui or ui
  2469     optlist = ("name templates style address port ipv6"
  2464     optlist = ("name templates style address port ipv6"
  2470                " accesslog errorlog webdir_conf")
  2465                " accesslog errorlog webdir_conf certificate")
  2471     for o in optlist.split():
  2466     for o in optlist.split():
  2472         if opts[o]:
  2467         if opts[o]:
  2473             parentui.setconfig("web", o, str(opts[o]))
  2468             parentui.setconfig("web", o, str(opts[o]))
  2474             if (repo is not None) and (repo.ui != parentui):
  2469             if (repo is not None) and (repo.ui != parentui):
  2475                 repo.ui.setconfig("web", o, str(opts[o]))
  2470                 repo.ui.setconfig("web", o, str(opts[o]))
  2648 
  2643 
  2649     Apply one or more compressed changegroup files generated by the
  2644     Apply one or more compressed changegroup files generated by the
  2650     bundle command.
  2645     bundle command.
  2651     """
  2646     """
  2652     fnames = (fname1,) + fnames
  2647     fnames = (fname1,) + fnames
  2653     result = None
       
  2654     for fname in fnames:
  2648     for fname in fnames:
  2655         if os.path.exists(fname):
  2649         if os.path.exists(fname):
  2656             f = open(fname, "rb")
  2650             f = open(fname, "rb")
  2657         else:
  2651         else:
  2658             f = urllib.urlopen(fname)
  2652             f = urllib.urlopen(fname)
  2755 commitopts = [
  2749 commitopts = [
  2756     ('m', 'message', '', _('use <text> as commit message')),
  2750     ('m', 'message', '', _('use <text> as commit message')),
  2757     ('l', 'logfile', '', _('read commit message from <file>')),
  2751     ('l', 'logfile', '', _('read commit message from <file>')),
  2758 ]
  2752 ]
  2759 
  2753 
       
  2754 commitopts2 = [
       
  2755     ('d', 'date', '', _('record datecode as commit date')),
       
  2756     ('u', 'user', '', _('record user as committer')),
       
  2757 ]
       
  2758 
  2760 table = {
  2759 table = {
  2761     "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
  2760     "^add": (add, walkopts + dryrunopts, _('hg add [OPTION]... [FILE]...')),
  2762     "addremove":
  2761     "addremove":
  2763         (addremove,
  2762         (addremove,
  2764          [('s', 'similarity', '',
  2763          [('s', 'similarity', '',
  2772           ('a', 'text', None, _('treat all files as text')),
  2771           ('a', 'text', None, _('treat all files as text')),
  2773           ('u', 'user', None, _('list the author')),
  2772           ('u', 'user', None, _('list the author')),
  2774           ('d', 'date', None, _('list the date')),
  2773           ('d', 'date', None, _('list the date')),
  2775           ('n', 'number', None, _('list the revision number (default)')),
  2774           ('n', 'number', None, _('list the revision number (default)')),
  2776           ('c', 'changeset', None, _('list the changeset')),
  2775           ('c', 'changeset', None, _('list the changeset')),
       
  2776           ('l', 'line-number', None,
       
  2777            _('show line number at the first appearance'))
  2777          ] + walkopts,
  2778          ] + walkopts,
  2778          _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] FILE...')),
  2779          _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
  2779     "archive":
  2780     "archive":
  2780         (archive,
  2781         (archive,
  2781          [('', 'no-decode', None, _('do not pass files through decoders')),
  2782          [('', 'no-decode', None, _('do not pass files through decoders')),
  2782           ('p', 'prefix', '', _('directory prefix for files in archive')),
  2783           ('p', 'prefix', '', _('directory prefix for files in archive')),
  2783           ('r', 'rev', '', _('revision to distribute')),
  2784           ('r', 'rev', '', _('revision to distribute')),
  2786          _('hg archive [OPTION]... DEST')),
  2787          _('hg archive [OPTION]... DEST')),
  2787     "backout":
  2788     "backout":
  2788         (backout,
  2789         (backout,
  2789          [('', 'merge', None,
  2790          [('', 'merge', None,
  2790            _('merge with old dirstate parent after backout')),
  2791            _('merge with old dirstate parent after backout')),
  2791           ('d', 'date', '', _('record datecode as commit date')),
       
  2792           ('', 'parent', '', _('parent to choose when backing out merge')),
  2792           ('', 'parent', '', _('parent to choose when backing out merge')),
  2793           ('u', 'user', '', _('record user as committer')),
       
  2794           ('r', 'rev', '', _('revision to backout')),
  2793           ('r', 'rev', '', _('revision to backout')),
  2795          ] + walkopts + commitopts,
  2794          ] + walkopts + commitopts + commitopts2,
  2796          _('hg backout [OPTION]... [-r] REV')),
  2795          _('hg backout [OPTION]... [-r] REV')),
  2797     "branch":
  2796     "branch":
  2798         (branch,
  2797         (branch,
  2799          [('f', 'force', None,
  2798          [('f', 'force', None,
  2800            _('set branch name even if it shadows an existing branch'))],
  2799            _('set branch name even if it shadows an existing branch'))],
  2832          _('hg clone [OPTION]... SOURCE [DEST]')),
  2831          _('hg clone [OPTION]... SOURCE [DEST]')),
  2833     "^commit|ci":
  2832     "^commit|ci":
  2834         (commit,
  2833         (commit,
  2835          [('A', 'addremove', None,
  2834          [('A', 'addremove', None,
  2836            _('mark new/missing files as added/removed before committing')),
  2835            _('mark new/missing files as added/removed before committing')),
  2837           ('d', 'date', '', _('record datecode as commit date')),
  2836          ] + walkopts + commitopts + commitopts2,
  2838           ('u', 'user', '', _('record user as commiter')),
       
  2839          ] + walkopts + commitopts,
       
  2840          _('hg commit [OPTION]... [FILE]...')),
  2837          _('hg commit [OPTION]... [FILE]...')),
  2841     "copy|cp":
  2838     "copy|cp":
  2842         (copy,
  2839         (copy,
  2843          [('A', 'after', None, _('record a copy that has already occurred')),
  2840          [('A', 'after', None, _('record a copy that has already occurred')),
  2844           ('f', 'force', None,
  2841           ('f', 'force', None,
  3024          ] + remoteopts,
  3021          ] + remoteopts,
  3025          _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
  3022          _('hg push [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
  3026     "debugrawcommit|rawcommit":
  3023     "debugrawcommit|rawcommit":
  3027         (rawcommit,
  3024         (rawcommit,
  3028          [('p', 'parent', [], _('parent')),
  3025          [('p', 'parent', [], _('parent')),
  3029           ('d', 'date', '', _('date code')),
       
  3030           ('u', 'user', '', _('user')),
       
  3031           ('F', 'files', '', _('file list'))
  3026           ('F', 'files', '', _('file list'))
  3032           ] + commitopts,
  3027           ] + commitopts + commitopts2,
  3033          _('hg debugrawcommit [OPTION]... [FILE]...')),
  3028          _('hg debugrawcommit [OPTION]... [FILE]...')),
  3034     "recover": (recover, [], _('hg recover')),
  3029     "recover": (recover, [], _('hg recover')),
  3035     "^remove|rm":
  3030     "^remove|rm":
  3036         (remove,
  3031         (remove,
  3037          [('A', 'after', None, _('record remove that has already occurred')),
  3032          [('A', 'after', None, _('record remove that has already occurred')),
  3073                                     ' (serve more than one repo)')),
  3068                                     ' (serve more than one repo)')),
  3074           ('', 'pid-file', '', _('name of file to write process ID to')),
  3069           ('', 'pid-file', '', _('name of file to write process ID to')),
  3075           ('', 'stdio', None, _('for remote clients')),
  3070           ('', 'stdio', None, _('for remote clients')),
  3076           ('t', 'templates', '', _('web templates to use')),
  3071           ('t', 'templates', '', _('web templates to use')),
  3077           ('', 'style', '', _('template style to use')),
  3072           ('', 'style', '', _('template style to use')),
  3078           ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
  3073           ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
       
  3074           ('', 'certificate', '', _('SSL certificate file'))],
  3079          _('hg serve [OPTION]...')),
  3075          _('hg serve [OPTION]...')),
  3080     "^status|st":
  3076     "^status|st":
  3081         (status,
  3077         (status,
  3082          [('A', 'all', None, _('show status of all files')),
  3078          [('A', 'all', None, _('show status of all files')),
  3083           ('m', 'modified', None, _('show only modified files')),
  3079           ('m', 'modified', None, _('show only modified files')),
  3096          _('hg status [OPTION]... [FILE]...')),
  3092          _('hg status [OPTION]... [FILE]...')),
  3097     "tag":
  3093     "tag":
  3098         (tag,
  3094         (tag,
  3099          [('f', 'force', None, _('replace existing tag')),
  3095          [('f', 'force', None, _('replace existing tag')),
  3100           ('l', 'local', None, _('make the tag local')),
  3096           ('l', 'local', None, _('make the tag local')),
  3101           ('m', 'message', '', _('message for tag commit log entry')),
       
  3102           ('d', 'date', '', _('record datecode as commit date')),
       
  3103           ('u', 'user', '', _('record user as commiter')),
       
  3104           ('r', 'rev', '', _('revision to tag')),
  3097           ('r', 'rev', '', _('revision to tag')),
  3105           ('', 'remove', None, _('remove a tag'))],
  3098           ('', 'remove', None, _('remove a tag')),
       
  3099           # -l/--local is already there, commitopts cannot be used
       
  3100           ('m', 'message', '', _('use <text> as commit message')),
       
  3101          ] + commitopts2,
  3106          _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
  3102          _('hg tag [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME')),
  3107     "tags": (tags, [], _('hg tags')),
  3103     "tags": (tags, [], _('hg tags')),
  3108     "tip":
  3104     "tip":
  3109         (tip,
  3105         (tip,
  3110          [('', 'style', '', _('display using template map file')),
  3106          [('', 'style', '', _('display using template map file')),
  3124          _('hg update [-C] [-d DATE] [[-r] REV]')),
  3120          _('hg update [-C] [-d DATE] [[-r] REV]')),
  3125     "verify": (verify, [], _('hg verify')),
  3121     "verify": (verify, [], _('hg verify')),
  3126     "version": (version_, [], _('hg version')),
  3122     "version": (version_, [], _('hg version')),
  3127 }
  3123 }
  3128 
  3124 
       
  3125 extensions.commandtable = table
       
  3126 
  3129 norepo = ("clone init version help debugancestor debugcomplete debugdata"
  3127 norepo = ("clone init version help debugancestor debugcomplete debugdata"
  3130           " debugindex debugindexdot debugdate debuginstall")
  3128           " debugindex debugindexdot debugdate debuginstall")
  3131 optionalrepo = ("paths serve showconfig")
  3129 optionalrepo = ("paths serve showconfig")
  3132 
  3130 
  3133 def dispatch(args):
  3131 def dispatch(args):