comparison mercurial/commands.py @ 1782:b9671b41e360

merge with crew
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Tue, 21 Feb 2006 16:46:38 +0100
parents 284fc722c342 b9fac31f34c9
children b942f5cfd326
comparison
equal deleted inserted replaced
1781:284fc722c342 1782:b9671b41e360
113 revs.reverse() 113 revs.reverse()
114 for rev in revs: 114 for rev in revs:
115 yield rev 115 yield rev
116 116
117 minrev, maxrev = min(revs), max(revs) 117 minrev, maxrev = min(revs), max(revs)
118 for file in files: 118 for file_ in files:
119 filelog = repo.file(file) 119 filelog = repo.file(file_)
120 # A zero count may be a directory or deleted file, so 120 # A zero count may be a directory or deleted file, so
121 # try to find matching entries on the slow path. 121 # try to find matching entries on the slow path.
122 if filelog.count() == 0: 122 if filelog.count() == 0:
123 slowpath = True 123 slowpath = True
124 break 124 break
125 for rev in filerevgen(filelog): 125 for rev in filerevgen(filelog):
126 if rev <= maxrev: 126 if rev <= maxrev:
127 if rev < minrev: 127 if rev < minrev:
128 break 128 break
129 fncache.setdefault(rev, []) 129 fncache.setdefault(rev, [])
130 fncache[rev].append(file) 130 fncache[rev].append(file_)
131 wanted[rev] = 1 131 wanted[rev] = 1
132 if slowpath: 132 if slowpath:
133 # The slow path checks files modified in every changeset. 133 # The slow path checks files modified in every changeset.
134 def changerevgen(): 134 def changerevgen():
135 for i in xrange(repo.changelog.count() - 1, -1, -window): 135 for i in xrange(repo.changelog.count() - 1, -1, -window):
259 return open(make_filename(repo, r, pat, node, total, seqno, revwidth, 259 return open(make_filename(repo, r, pat, node, total, seqno, revwidth,
260 pathname), 260 pathname),
261 mode) 261 mode)
262 262
263 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always, 263 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
264 changes=None, text=False): 264 changes=None, text=False, opts={}):
265 if not changes: 265 if not changes:
266 changes = repo.changes(node1, node2, files, match=match) 266 changes = repo.changes(node1, node2, files, match=match)
267 modified, added, removed, deleted, unknown = changes 267 modified, added, removed, deleted, unknown = changes
268 if files: 268 if files:
269 modified, added, removed = map(lambda x: filterfiles(files, x), 269 modified, added, removed = map(lambda x: filterfiles(files, x),
294 change = repo.changelog.read(node1) 294 change = repo.changelog.read(node1)
295 mmap = repo.manifest.read(change[0]) 295 mmap = repo.manifest.read(change[0])
296 date1 = util.datestr(change[2]) 296 date1 = util.datestr(change[2])
297 297
298 diffopts = ui.diffopts() 298 diffopts = ui.diffopts()
299 showfunc = diffopts['showfunc'] 299 showfunc = opts.get('show_function') or diffopts['showfunc']
300 ignorews = diffopts['ignorews'] 300 ignorews = opts.get('ignore_all_space') or diffopts['ignorews']
301 for f in modified: 301 for f in modified:
302 to = None 302 to = None
303 if f in mmap: 303 if f in mmap:
304 to = repo.file(f).read(mmap[f]) 304 to = repo.file(f).read(mmap[f])
305 tn = read(f) 305 tn = read(f)
445 if cmd == "shortlist" and not f.startswith("^"): 445 if cmd == "shortlist" and not f.startswith("^"):
446 continue 446 continue
447 f = f.lstrip("^") 447 f = f.lstrip("^")
448 if not ui.debugflag and f.startswith("debug"): 448 if not ui.debugflag and f.startswith("debug"):
449 continue 449 continue
450 d = ""
451 doc = e[0].__doc__ 450 doc = e[0].__doc__
452 if not doc: 451 if not doc:
453 doc = _("(No help text available)") 452 doc = _("(No help text available)")
454 h[f] = doc.splitlines(0)[0].rstrip() 453 h[f] = doc.splitlines(0)[0].rstrip()
455 cmds[f] = c.lstrip("^") 454 cmds[f] = c.lstrip("^")
620 """ 619 """
621 f = open(fname, "wb") 620 f = open(fname, "wb")
622 dest = ui.expandpath(dest, repo.root) 621 dest = ui.expandpath(dest, repo.root)
623 other = hg.repository(ui, dest) 622 other = hg.repository(ui, dest)
624 o = repo.findoutgoing(other) 623 o = repo.findoutgoing(other)
625 cg = repo.changegroup(o) 624 cg = repo.changegroup(o, 'bundle')
626 625
627 try: 626 try:
628 f.write("HG10") 627 f.write("HG10")
629 z = bz2.BZ2Compressor(9) 628 z = bz2.BZ2Compressor(9)
630 while 1: 629 while 1:
723 try: 722 try:
724 # we use a lock here because if we race with commit, we 723 # we use a lock here because if we race with commit, we
725 # can end up with extra data in the cloned revlogs that's 724 # can end up with extra data in the cloned revlogs that's
726 # not pointed to by changesets, thus causing verify to 725 # not pointed to by changesets, thus causing verify to
727 # fail 726 # fail
728 l1 = lock.lock(os.path.join(source, ".hg", "lock")) 727 l1 = other.lock()
729 except OSError: 728 except lock.LockException:
730 copy = False 729 copy = False
731 730
732 if copy: 731 if copy:
733 # we lock here to avoid premature writing to the target 732 # we lock here to avoid premature writing to the target
734 os.mkdir(os.path.join(dest, ".hg")) 733 os.mkdir(os.path.join(dest, ".hg"))
816 815
817 def okaytocopy(abs, rel, exact): 816 def okaytocopy(abs, rel, exact):
818 reasons = {'?': _('is not managed'), 817 reasons = {'?': _('is not managed'),
819 'a': _('has been marked for add'), 818 'a': _('has been marked for add'),
820 'r': _('has been marked for remove')} 819 'r': _('has been marked for remove')}
821 reason = reasons.get(repo.dirstate.state(abs)) 820 state = repo.dirstate.state(abs)
821 reason = reasons.get(state)
822 if reason: 822 if reason:
823 if state == 'a':
824 origsrc = repo.dirstate.copied(abs)
825 if origsrc is not None:
826 return origsrc
823 if exact: 827 if exact:
824 ui.warn(_('%s: not copying - file %s\n') % (rel, reason)) 828 ui.warn(_('%s: not copying - file %s\n') % (rel, reason))
825 else: 829 else:
826 return True 830 return abs
827 831
828 def copy(abssrc, relsrc, target, exact): 832 def copy(origsrc, abssrc, relsrc, target, exact):
829 abstarget = util.canonpath(repo.root, cwd, target) 833 abstarget = util.canonpath(repo.root, cwd, target)
830 reltarget = util.pathto(cwd, abstarget) 834 reltarget = util.pathto(cwd, abstarget)
831 prevsrc = targets.get(abstarget) 835 prevsrc = targets.get(abstarget)
832 if prevsrc is not None: 836 if prevsrc is not None:
833 ui.warn(_('%s: not overwriting - %s collides with %s\n') % 837 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
862 errors += 1 866 errors += 1
863 return 867 return
864 if ui.verbose or not exact: 868 if ui.verbose or not exact:
865 ui.status(_('copying %s to %s\n') % (relsrc, reltarget)) 869 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
866 targets[abstarget] = abssrc 870 targets[abstarget] = abssrc
867 repo.copy(abssrc, abstarget) 871 repo.copy(origsrc, abstarget)
868 copied.append((abssrc, relsrc, exact)) 872 copied.append((abssrc, relsrc, exact))
869 873
870 def targetpathfn(pat, dest, srcs): 874 def targetpathfn(pat, dest, srcs):
871 if os.path.isdir(pat): 875 if os.path.isdir(pat):
872 abspfx = util.canonpath(repo.root, cwd, pat) 876 abspfx = util.canonpath(repo.root, cwd, pat)
936 tfn = targetpathfn 940 tfn = targetpathfn
937 copylist = [] 941 copylist = []
938 for pat in pats: 942 for pat in pats:
939 srcs = [] 943 srcs = []
940 for tag, abssrc, relsrc, exact in walk(repo, [pat], opts): 944 for tag, abssrc, relsrc, exact in walk(repo, [pat], opts):
941 if okaytocopy(abssrc, relsrc, exact): 945 origsrc = okaytocopy(abssrc, relsrc, exact)
942 srcs.append((abssrc, relsrc, exact)) 946 if origsrc:
947 srcs.append((origsrc, abssrc, relsrc, exact))
943 if not srcs: 948 if not srcs:
944 continue 949 continue
945 copylist.append((tfn(pat, dest, srcs), srcs)) 950 copylist.append((tfn(pat, dest, srcs), srcs))
946 if not copylist: 951 if not copylist:
947 raise util.Abort(_('no files to copy')) 952 raise util.Abort(_('no files to copy'))
948 953
949 for targetpath, srcs in copylist: 954 for targetpath, srcs in copylist:
950 for abssrc, relsrc, exact in srcs: 955 for origsrc, abssrc, relsrc, exact in srcs:
951 copy(abssrc, relsrc, targetpath(abssrc), exact) 956 copy(origsrc, abssrc, relsrc, targetpath(abssrc), exact)
952 957
953 if errors: 958 if errors:
954 ui.warn(_('(consider using --after)\n')) 959 ui.warn(_('(consider using --after)\n'))
955 return errors, copied 960 return errors, copied
956 961
977 def debugancestor(ui, index, rev1, rev2): 982 def debugancestor(ui, index, rev1, rev2):
978 """find the ancestor revision of two revisions in a given index""" 983 """find the ancestor revision of two revisions in a given index"""
979 r = revlog.revlog(util.opener(os.getcwd()), index, "") 984 r = revlog.revlog(util.opener(os.getcwd()), index, "")
980 a = r.ancestor(r.lookup(rev1), r.lookup(rev2)) 985 a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
981 ui.write("%d:%s\n" % (r.rev(a), hex(a))) 986 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
987
988 def debugrebuildstate(ui, repo, rev=None):
989 """rebuild the dirstate as it would look like for the given revision"""
990 if not rev:
991 rev = repo.changelog.tip()
992 else:
993 rev = repo.lookup(rev)
994 change = repo.changelog.read(rev)
995 n = change[0]
996 files = repo.manifest.readflags(n)
997 wlock = repo.wlock()
998 repo.dirstate.rebuild(rev, files.iteritems())
982 999
983 def debugcheckstate(ui, repo): 1000 def debugcheckstate(ui, repo):
984 """validate the correctness of the current dirstate""" 1001 """validate the correctness of the current dirstate"""
985 parent1, parent2 = repo.dirstate.parents() 1002 parent1, parent2 = repo.dirstate.parents()
986 repo.dirstate.read() 1003 repo.dirstate.read()
1138 raise util.Abort(_("too many revisions to diff")) 1155 raise util.Abort(_("too many revisions to diff"))
1139 1156
1140 fns, matchfn, anypats = matchpats(repo, pats, opts) 1157 fns, matchfn, anypats = matchpats(repo, pats, opts)
1141 1158
1142 dodiff(sys.stdout, ui, repo, node1, node2, fns, match=matchfn, 1159 dodiff(sys.stdout, ui, repo, node1, node2, fns, match=matchfn,
1143 text=opts['text']) 1160 text=opts['text'], opts=opts)
1144 1161
1145 def doexport(ui, repo, changeset, seqno, total, revwidth, opts): 1162 def doexport(ui, repo, changeset, seqno, total, revwidth, opts):
1146 node = repo.lookup(changeset) 1163 node = repo.lookup(changeset)
1147 parents = [p for p in repo.changelog.parents(node) if p != nullid] 1164 parents = [p for p in repo.changelog.parents(node) if p != nullid]
1148 if opts['switch_parent']: 1165 if opts['switch_parent']:
1282 m = matches[rev][fn] 1299 m = matches[rev][fn]
1283 for lnum, cstart, cend, line in matchlines(body): 1300 for lnum, cstart, cend, line in matchlines(body):
1284 s = linestate(line, lnum, cstart, cend) 1301 s = linestate(line, lnum, cstart, cend)
1285 m[s] = s 1302 m[s] = s
1286 1303
1304 # FIXME: prev isn't used, why ?
1287 prev = {} 1305 prev = {}
1288 ucache = {} 1306 ucache = {}
1289 def display(fn, rev, states, prevstates): 1307 def display(fn, rev, states, prevstates):
1290 diff = list(sets.Set(states).symmetric_difference(sets.Set(prevstates))) 1308 diff = list(sets.Set(states).symmetric_difference(sets.Set(prevstates)))
1291 diff.sort(lambda x, y: cmp(x.linenum, y.linenum)) 1309 diff.sort(lambda x, y: cmp(x.linenum, y.linenum))
1591 def debug(self, *args): 1609 def debug(self, *args):
1592 if self.debugflag: 1610 if self.debugflag:
1593 self.write(*args) 1611 self.write(*args)
1594 def __getattr__(self, key): 1612 def __getattr__(self, key):
1595 return getattr(self.ui, key) 1613 return getattr(self.ui, key)
1614
1596 changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts) 1615 changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts)
1616
1617 if opts['limit']:
1618 try:
1619 limit = int(opts['limit'])
1620 except ValueError:
1621 raise util.Abort(_('limit must be a positive integer'))
1622 if limit <= 0: raise util.Abort(_('limit must be positive'))
1623 else:
1624 limit = sys.maxint
1625 count = 0
1626
1597 for st, rev, fns in changeiter: 1627 for st, rev, fns in changeiter:
1598 if st == 'window': 1628 if st == 'window':
1599 du = dui(ui) 1629 du = dui(ui)
1600 elif st == 'add': 1630 elif st == 'add':
1601 du.bump(rev) 1631 du.bump(rev)
1605 if opts['no_merges'] and len(parents) == 2: 1635 if opts['no_merges'] and len(parents) == 2:
1606 continue 1636 continue
1607 if opts['only_merges'] and len(parents) != 2: 1637 if opts['only_merges'] and len(parents) != 2:
1608 continue 1638 continue
1609 1639
1610 br = None
1611 if opts['keyword']: 1640 if opts['keyword']:
1612 changes = getchange(rev) 1641 changes = getchange(rev)
1613 miss = 0 1642 miss = 0
1614 for k in [kw.lower() for kw in opts['keyword']]: 1643 for k in [kw.lower() for kw in opts['keyword']]:
1615 if not (k in changes[1].lower() or 1644 if not (k in changes[1].lower() or
1618 miss = 1 1647 miss = 1
1619 break 1648 break
1620 if miss: 1649 if miss:
1621 continue 1650 continue
1622 1651
1623 if opts['branch']: 1652 br = None
1653 if opts['branches']:
1624 br = repo.branchlookup([repo.changelog.node(rev)]) 1654 br = repo.branchlookup([repo.changelog.node(rev)])
1625 1655
1626 show_changeset(du, repo, rev, brinfo=br) 1656 show_changeset(du, repo, rev, brinfo=br)
1627 if opts['patch']: 1657 if opts['patch']:
1628 prev = (parents and parents[0]) or nullid 1658 prev = (parents and parents[0]) or nullid
1629 dodiff(du, du, repo, prev, changenode, match=matchfn) 1659 dodiff(du, du, repo, prev, changenode, match=matchfn)
1630 du.write("\n\n") 1660 du.write("\n\n")
1631 elif st == 'iter': 1661 elif st == 'iter':
1632 for args in du.hunk[rev]: 1662 if count == limit: break
1633 ui.write(*args) 1663 if du.hunk[rev]:
1664 count += 1
1665 for args in du.hunk[rev]:
1666 ui.write(*args)
1634 1667
1635 def manifest(ui, repo, rev=None): 1668 def manifest(ui, repo, rev=None):
1636 """output the latest or given revision of the project manifest 1669 """output the latest or given revision of the project manifest
1637 1670
1638 Print a list of version controlled files for the given revision. 1671 Print a list of version controlled files for the given revision.
1679 if opts['patch']: 1712 if opts['patch']:
1680 prev = (parents and parents[0]) or nullid 1713 prev = (parents and parents[0]) or nullid
1681 dodiff(ui, ui, repo, prev, n) 1714 dodiff(ui, ui, repo, prev, n)
1682 ui.write("\n") 1715 ui.write("\n")
1683 1716
1684 def parents(ui, repo, rev=None): 1717 def parents(ui, repo, rev=None, branches=None):
1685 """show the parents of the working dir or revision 1718 """show the parents of the working dir or revision
1686 1719
1687 Print the working directory's parent revisions. 1720 Print the working directory's parent revisions.
1688 """ 1721 """
1689 if rev: 1722 if rev:
1690 p = repo.changelog.parents(repo.lookup(rev)) 1723 p = repo.changelog.parents(repo.lookup(rev))
1691 else: 1724 else:
1692 p = repo.dirstate.parents() 1725 p = repo.dirstate.parents()
1693 1726
1727 br = None
1728 if branches is not None:
1729 br = repo.branchlookup(p)
1694 for n in p: 1730 for n in p:
1695 if n != nullid: 1731 if n != nullid:
1696 show_changeset(ui, repo, changenode=n) 1732 show_changeset(ui, repo, changenode=n, brinfo=br)
1697 1733
1698 def paths(ui, search=None): 1734 def paths(ui, search=None):
1699 """show definition of symbolic path names 1735 """show definition of symbolic path names
1700 1736
1701 Show definition of symbolic path name NAME. If no name is given, show 1737 Show definition of symbolic path name NAME. If no name is given, show
1997 elif cmd == "changegroup": 2033 elif cmd == "changegroup":
1998 nodes = [] 2034 nodes = []
1999 arg, roots = getarg() 2035 arg, roots = getarg()
2000 nodes = map(bin, roots.split(" ")) 2036 nodes = map(bin, roots.split(" "))
2001 2037
2002 cg = repo.changegroup(nodes) 2038 cg = repo.changegroup(nodes, 'serve')
2003 while 1: 2039 while 1:
2004 d = cg.read(4096) 2040 d = cg.read(4096)
2005 if not d: 2041 if not d:
2006 break 2042 break
2007 fout.write(d) 2043 fout.write(d)
2019 2055
2020 optlist = "name templates style address port ipv6 accesslog errorlog" 2056 optlist = "name templates style address port ipv6 accesslog errorlog"
2021 for o in optlist.split(): 2057 for o in optlist.split():
2022 if opts[o]: 2058 if opts[o]:
2023 ui.setconfig("web", o, opts[o]) 2059 ui.setconfig("web", o, opts[o])
2060
2061 if opts['daemon'] and not opts['daemon_pipefds']:
2062 rfd, wfd = os.pipe()
2063 args = sys.argv[:]
2064 args.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
2065 pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
2066 args[0], args)
2067 os.close(wfd)
2068 os.read(rfd, 1)
2069 os._exit(0)
2024 2070
2025 try: 2071 try:
2026 httpd = hgweb.create_server(repo) 2072 httpd = hgweb.create_server(repo)
2027 except socket.error, inst: 2073 except socket.error, inst:
2028 raise util.Abort(_('cannot start server: ') + inst.args[1]) 2074 raise util.Abort(_('cannot start server: ') + inst.args[1])
2038 pass 2084 pass
2039 if port != 80: 2085 if port != 80:
2040 ui.status(_('listening at http://%s:%d/\n') % (addr, port)) 2086 ui.status(_('listening at http://%s:%d/\n') % (addr, port))
2041 else: 2087 else:
2042 ui.status(_('listening at http://%s/\n') % addr) 2088 ui.status(_('listening at http://%s/\n') % addr)
2089
2090 if opts['pid_file']:
2091 fp = open(opts['pid_file'], 'w')
2092 fp.write(str(os.getpid()))
2093 fp.close()
2094
2095 if opts['daemon_pipefds']:
2096 rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')]
2097 os.close(rfd)
2098 os.write(wfd, 'y')
2099 os.close(wfd)
2100 sys.stdout.flush()
2101 sys.stderr.flush()
2102 fd = os.open(util.nulldev, os.O_RDWR)
2103 if fd != 0: os.dup2(fd, 0)
2104 if fd != 1: os.dup2(fd, 1)
2105 if fd != 2: os.dup2(fd, 2)
2106 if fd not in (0, 1, 2): os.close(fd)
2107
2043 httpd.serve_forever() 2108 httpd.serve_forever()
2044 2109
2045 def status(ui, repo, *pats, **opts): 2110 def status(ui, repo, *pats, **opts):
2046 """show changed files in the working directory 2111 """show changed files in the working directory
2047 2112
2114 disallowed = (revrangesep, '\r', '\n') 2179 disallowed = (revrangesep, '\r', '\n')
2115 for c in disallowed: 2180 for c in disallowed:
2116 if name.find(c) >= 0: 2181 if name.find(c) >= 0:
2117 raise util.Abort(_("%s cannot be used in a tag name") % repr(c)) 2182 raise util.Abort(_("%s cannot be used in a tag name") % repr(c))
2118 2183
2184 repo.hook('pretag', throw=True, node=r, tag=name,
2185 local=int(not not opts['local']))
2186
2119 if opts['local']: 2187 if opts['local']:
2120 repo.opener("localtags", "a").write("%s %s\n" % (r, name)) 2188 repo.opener("localtags", "a").write("%s %s\n" % (r, name))
2189 repo.hook('tag', node=r, tag=name, local=1)
2121 return 2190 return
2122 2191
2123 for x in repo.changes(): 2192 for x in repo.changes():
2124 if ".hgtags" in x: 2193 if ".hgtags" in x:
2125 raise util.Abort(_("working copy of .hgtags is changed " 2194 raise util.Abort(_("working copy of .hgtags is changed "
2131 2200
2132 message = (opts['message'] or 2201 message = (opts['message'] or
2133 _("Added tag %s for changeset %s") % (name, r)) 2202 _("Added tag %s for changeset %s") % (name, r))
2134 try: 2203 try:
2135 repo.commit([".hgtags"], message, opts['user'], opts['date']) 2204 repo.commit([".hgtags"], message, opts['user'], opts['date'])
2205 repo.hook('tag', node=r, tag=name, local=0)
2136 except ValueError, inst: 2206 except ValueError, inst:
2137 raise util.Abort(str(inst)) 2207 raise util.Abort(str(inst))
2138 2208
2139 def tags(ui, repo): 2209 def tags(ui, repo):
2140 """list repository tags 2210 """list repository tags
2151 r = "%5d:%s" % (repo.changelog.rev(n), hex(n)) 2221 r = "%5d:%s" % (repo.changelog.rev(n), hex(n))
2152 except KeyError: 2222 except KeyError:
2153 r = " ?:?" 2223 r = " ?:?"
2154 ui.write("%-30s %s\n" % (t, r)) 2224 ui.write("%-30s %s\n" % (t, r))
2155 2225
2156 def tip(ui, repo): 2226 def tip(ui, repo, **opts):
2157 """show the tip revision 2227 """show the tip revision
2158 2228
2159 Show the tip revision. 2229 Show the tip revision.
2160 """ 2230 """
2161 n = repo.changelog.tip() 2231 n = repo.changelog.tip()
2162 show_changeset(ui, repo, changenode=n) 2232 br = None
2233 if opts['branches']:
2234 br = repo.branchlookup([n])
2235 show_changeset(ui, repo, changenode=n, brinfo=br)
2236 if opts['patch']:
2237 dodiff(ui, ui, repo, repo.changelog.parents(n)[0], n)
2163 2238
2164 def unbundle(ui, repo, fname, **opts): 2239 def unbundle(ui, repo, fname, **opts):
2165 """apply a changegroup file 2240 """apply a changegroup file
2166 2241
2167 Apply a compressed changegroup file generated by the bundle 2242 Apply a compressed changegroup file generated by the bundle
2315 ('A', 'after', None, _('record a copy that has already occurred')), 2390 ('A', 'after', None, _('record a copy that has already occurred')),
2316 ('f', 'force', None, 2391 ('f', 'force', None,
2317 _('forcibly copy over an existing managed file'))], 2392 _('forcibly copy over an existing managed file'))],
2318 _('hg copy [OPTION]... [SOURCE]... DEST')), 2393 _('hg copy [OPTION]... [SOURCE]... DEST')),
2319 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')), 2394 "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
2395 "debugrebuildstate":
2396 (debugrebuildstate,
2397 [('r', 'rev', "", _("revision to rebuild to"))],
2398 _('debugrebuildstate [-r REV] [REV]')),
2320 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')), 2399 "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
2321 "debugconfig": (debugconfig, [], _('debugconfig')), 2400 "debugconfig": (debugconfig, [], _('debugconfig')),
2322 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')), 2401 "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
2323 "debugstate": (debugstate, [], _('debugstate')), 2402 "debugstate": (debugstate, [], _('debugstate')),
2324 "debugdata": (debugdata, [], _('debugdata FILE REV')), 2403 "debugdata": (debugdata, [], _('debugdata FILE REV')),
2333 "^diff": 2412 "^diff":
2334 (diff, 2413 (diff,
2335 [('r', 'rev', [], _('revision')), 2414 [('r', 'rev', [], _('revision')),
2336 ('a', 'text', None, _('treat all files as text')), 2415 ('a', 'text', None, _('treat all files as text')),
2337 ('I', 'include', [], _('include names matching the given patterns')), 2416 ('I', 'include', [], _('include names matching the given patterns')),
2338 ('X', 'exclude', [], _('exclude names matching the given patterns'))], 2417 ('p', 'show-function', None,
2418 _('show which function each change is in')),
2419 ('w', 'ignore-all-space', None,
2420 _('ignore white space when comparing lines')),
2421 ('X', 'exclude', [],
2422 _('exclude names matching the given patterns'))],
2339 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')), 2423 _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
2340 "^export": 2424 "^export":
2341 (export, 2425 (export,
2342 [('o', 'output', '', _('print output to file with formatted name')), 2426 [('o', 'output', '', _('print output to file with formatted name')),
2343 ('a', 'text', None, _('treat all files as text')), 2427 ('a', 'text', None, _('treat all files as text')),
2361 ('r', 'rev', [], _('search in given revision range')), 2445 ('r', 'rev', [], _('search in given revision range')),
2362 ('u', 'user', None, _('print user who committed change'))], 2446 ('u', 'user', None, _('print user who committed change'))],
2363 _('hg grep [OPTION]... PATTERN [FILE]...')), 2447 _('hg grep [OPTION]... PATTERN [FILE]...')),
2364 "heads": 2448 "heads":
2365 (heads, 2449 (heads,
2366 [('b', 'branches', None, _('find branch info')), 2450 [('b', 'branches', None, _('show branches')),
2367 ('r', 'rev', '', _('show only heads which are descendants of rev'))], 2451 ('r', 'rev', '', _('show only heads which are descendants of rev'))],
2368 _('hg heads [-b] [-r <rev>]')), 2452 _('hg heads [-b] [-r <rev>]')),
2369 "help": (help_, [], _('hg help [COMMAND]')), 2453 "help": (help_, [], _('hg help [COMMAND]')),
2370 "identify|id": (identify, [], _('hg identify')), 2454 "identify|id": (identify, [], _('hg identify')),
2371 "import|patch": 2455 "import|patch":
2395 _('hg locate [OPTION]... [PATTERN]...')), 2479 _('hg locate [OPTION]... [PATTERN]...')),
2396 "^log|history": 2480 "^log|history":
2397 (log, 2481 (log,
2398 [('I', 'include', [], _('include names matching the given patterns')), 2482 [('I', 'include', [], _('include names matching the given patterns')),
2399 ('X', 'exclude', [], _('exclude names matching the given patterns')), 2483 ('X', 'exclude', [], _('exclude names matching the given patterns')),
2400 ('b', 'branch', None, _('show branches')), 2484 ('b', 'branches', None, _('show branches')),
2401 ('k', 'keyword', [], _('search for a keyword')), 2485 ('k', 'keyword', [], _('search for a keyword')),
2486 ('l', 'limit', '', _('limit number of changes displayed')),
2402 ('r', 'rev', [], _('show the specified revision or range')), 2487 ('r', 'rev', [], _('show the specified revision or range')),
2403 ('M', 'no-merges', None, _('do not show merges')), 2488 ('M', 'no-merges', None, _('do not show merges')),
2404 ('m', 'only-merges', None, _('show only merges')), 2489 ('m', 'only-merges', None, _('show only merges')),
2405 ('p', 'patch', None, _('show patch'))], 2490 ('p', 'patch', None, _('show patch'))],
2406 _('hg log [-I] [-X] [-r REV]... [-p] [FILE]')), 2491 _('hg log [-I] [-X] [-r REV]... [-p] [FILE]')),
2408 "outgoing|out": (outgoing, 2493 "outgoing|out": (outgoing,
2409 [('M', 'no-merges', None, _('do not show merges')), 2494 [('M', 'no-merges', None, _('do not show merges')),
2410 ('p', 'patch', None, _('show patch')), 2495 ('p', 'patch', None, _('show patch')),
2411 ('n', 'newest-first', None, _('show newest record first'))], 2496 ('n', 'newest-first', None, _('show newest record first'))],
2412 _('hg outgoing [-p] [-n] [-M] [DEST]')), 2497 _('hg outgoing [-p] [-n] [-M] [DEST]')),
2413 "^parents": (parents, [], _('hg parents [REV]')), 2498 "^parents":
2499 (parents,
2500 [('b', 'branches', None, _('show branches'))],
2501 _('hg parents [-b] [REV]')),
2414 "paths": (paths, [], _('hg paths [NAME]')), 2502 "paths": (paths, [], _('hg paths [NAME]')),
2415 "^pull": 2503 "^pull":
2416 (pull, 2504 (pull,
2417 [('u', 'update', None, 2505 [('u', 'update', None,
2418 _('update the working directory to tip after pull')), 2506 _('update the working directory to tip after pull')),
2460 _('hg revert [-n] [-r REV] [NAME]...')), 2548 _('hg revert [-n] [-r REV] [NAME]...')),
2461 "root": (root, [], _('hg root')), 2549 "root": (root, [], _('hg root')),
2462 "^serve": 2550 "^serve":
2463 (serve, 2551 (serve,
2464 [('A', 'accesslog', '', _('name of access log file to write to')), 2552 [('A', 'accesslog', '', _('name of access log file to write to')),
2553 ('d', 'daemon', None, _('run server in background')),
2554 ('', 'daemon-pipefds', '', _('used internally by daemon mode')),
2465 ('E', 'errorlog', '', _('name of error log file to write to')), 2555 ('E', 'errorlog', '', _('name of error log file to write to')),
2466 ('p', 'port', 0, _('port to use (default: 8000)')), 2556 ('p', 'port', 0, _('port to use (default: 8000)')),
2467 ('a', 'address', '', _('address to use')), 2557 ('a', 'address', '', _('address to use')),
2468 ('n', 'name', '', 2558 ('n', 'name', '',
2469 _('name to show in web pages (default: working dir)')), 2559 _('name to show in web pages (default: working dir)')),
2560 ('', 'pid-file', '', _('name of file to write process ID to')),
2470 ('', 'stdio', None, _('for remote clients')), 2561 ('', 'stdio', None, _('for remote clients')),
2471 ('t', 'templates', '', _('web templates to use')), 2562 ('t', 'templates', '', _('web templates to use')),
2472 ('', 'style', '', _('template style to use')), 2563 ('', 'style', '', _('template style to use')),
2473 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))], 2564 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4'))],
2474 _('hg serve [OPTION]...')), 2565 _('hg serve [OPTION]...')),
2492 ('d', 'date', '', _('record datecode as commit date')), 2583 ('d', 'date', '', _('record datecode as commit date')),
2493 ('u', 'user', '', _('record user as commiter')), 2584 ('u', 'user', '', _('record user as commiter')),
2494 ('r', 'rev', '', _('revision to tag'))], 2585 ('r', 'rev', '', _('revision to tag'))],
2495 _('hg tag [-r REV] [OPTION]... NAME')), 2586 _('hg tag [-r REV] [OPTION]... NAME')),
2496 "tags": (tags, [], _('hg tags')), 2587 "tags": (tags, [], _('hg tags')),
2497 "tip": (tip, [], _('hg tip')), 2588 "tip":
2589 (tip,
2590 [('b', 'branches', None, _('show branches')),
2591 ('p', 'patch', None, _('show patch'))],
2592 _('hg [-b] [-p] tip')),
2498 "unbundle": 2593 "unbundle":
2499 (unbundle, 2594 (unbundle,
2500 [('u', 'update', None, 2595 [('u', 'update', None,
2501 _('update the working directory to tip after unbundle'))], 2596 _('update the working directory to tip after unbundle'))],
2502 _('hg unbundle [-u] FILE')), 2597 _('hg unbundle [-u] FILE')),
2532 " debugindex debugindexdot paths") 2627 " debugindex debugindexdot paths")
2533 2628
2534 def find(cmd): 2629 def find(cmd):
2535 """Return (aliases, command table entry) for command string.""" 2630 """Return (aliases, command table entry) for command string."""
2536 choice = None 2631 choice = None
2632 count = 0
2537 for e in table.keys(): 2633 for e in table.keys():
2538 aliases = e.lstrip("^").split("|") 2634 aliases = e.lstrip("^").split("|")
2539 if cmd in aliases: 2635 if cmd in aliases:
2540 return aliases, table[e] 2636 return aliases, table[e]
2541 for a in aliases: 2637 for a in aliases:
2542 if a.startswith(cmd): 2638 if a.startswith(cmd):
2543 if choice: 2639 count += 1
2544 raise AmbiguousCommand(cmd) 2640 choice = aliases, table[e]
2545 else: 2641 break
2546 choice = aliases, table[e] 2642
2547 break 2643 if count > 1:
2644 raise AmbiguousCommand(cmd)
2645
2548 if choice: 2646 if choice:
2549 return choice 2647 return choice
2550 2648
2551 raise UnknownCommand(cmd) 2649 raise UnknownCommand(cmd)
2552 2650