comparison mercurial/commands.py @ 1065:6e94c0365d98

Cleanups to commands.py
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 26 Aug 2005 15:19:18 +0200
parents 6d5a62a549fa
children ea878688221e
comparison
equal deleted inserted replaced
1064:8d791bea49d4 1065:6e94c0365d98
42 yield src, fn, util.pathto(cwd, fn), fn in exact 42 yield src, fn, util.pathto(cwd, fn), fn in exact
43 return files, matchfn, walk() 43 return files, matchfn, walk()
44 44
45 def walk(repo, pats, opts, head=''): 45 def walk(repo, pats, opts, head=''):
46 files, matchfn, results = makewalk(repo, pats, opts, head) 46 files, matchfn, results = makewalk(repo, pats, opts, head)
47 for r in results: yield r 47 for r in results:
48 yield r
48 49
49 def walkchangerevs(ui, repo, cwd, pats, opts): 50 def walkchangerevs(ui, repo, cwd, pats, opts):
50 # This code most commonly needs to iterate backwards over the 51 # This code most commonly needs to iterate backwards over the
51 # history it is interested in. Doing so has awful 52 # history it is interested in. Doing so has awful
52 # (quadratic-looking) performance, so we use iterators in a 53 # (quadratic-looking) performance, so we use iterators in a
86 if filelog.count() == 0: 87 if filelog.count() == 0:
87 slowpath = True 88 slowpath = True
88 break 89 break
89 for rev in filerevgen(filelog): 90 for rev in filerevgen(filelog):
90 if rev <= maxrev: 91 if rev <= maxrev:
91 if rev < minrev: break 92 if rev < minrev:
93 break
92 fncache.setdefault(rev, []) 94 fncache.setdefault(rev, [])
93 fncache[rev].append(file) 95 fncache[rev].append(file)
94 wanted[rev] = 1 96 wanted[rev] = 1
95 if slowpath: 97 if slowpath:
96 # The slow path checks files modified in every changeset. 98 # The slow path checks files modified in every changeset.
105 fncache[rev] = matches 107 fncache[rev] = matches
106 wanted[rev] = 1 108 wanted[rev] = 1
107 109
108 for i in xrange(0, len(revs), window): 110 for i in xrange(0, len(revs), window):
109 yield 'window', revs[0] < revs[-1], revs[-1] 111 yield 'window', revs[0] < revs[-1], revs[-1]
110 nrevs = [rev for rev in revs[i : min(i + window, len(revs))] 112 nrevs = [rev for rev in revs[i:min(i+window, len(revs))]
111 if rev in wanted] 113 if rev in wanted]
112 srevs = list(nrevs) 114 srevs = list(nrevs)
113 srevs.sort() 115 srevs.sort()
114 for rev in srevs: 116 for rev in srevs:
115 fns = fncache.get(rev) 117 fns = fncache.get(rev)
203 inst.args[0]) 205 inst.args[0])
204 206
205 def make_file(repo, r, pat, node=None, 207 def make_file(repo, r, pat, node=None,
206 total=None, seqno=None, revwidth=None, mode='wb'): 208 total=None, seqno=None, revwidth=None, mode='wb'):
207 if not pat or pat == '-': 209 if not pat or pat == '-':
208 if 'w' in mode: return sys.stdout 210 return 'w' in mode and sys.stdout or sys.stdin
209 else: return sys.stdin
210 if hasattr(pat, 'write') and 'w' in mode: 211 if hasattr(pat, 'write') and 'w' in mode:
211 return pat 212 return pat
212 if hasattr(pat, 'read') and 'r' in mode: 213 if hasattr(pat, 'read') and 'r' in mode:
213 return pat 214 return pat
214 return open(make_filename(repo, r, pat, node, total, seqno, revwidth), 215 return open(make_filename(repo, r, pat, node, total, seqno, revwidth),
453 """add all new files, delete all missing files""" 454 """add all new files, delete all missing files"""
454 add, remove = [], [] 455 add, remove = [], []
455 for src, abs, rel, exact in walk(repo, pats, opts): 456 for src, abs, rel, exact in walk(repo, pats, opts):
456 if src == 'f' and repo.dirstate.state(abs) == '?': 457 if src == 'f' and repo.dirstate.state(abs) == '?':
457 add.append(abs) 458 add.append(abs)
458 if not exact: ui.status('adding ', rel, '\n') 459 if not exact:
460 ui.status('adding ', rel, '\n')
459 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel): 461 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel):
460 remove.append(abs) 462 remove.append(abs)
461 if not exact: ui.status('removing ', rel, '\n') 463 if not exact:
464 ui.status('removing ', rel, '\n')
462 repo.add(add) 465 repo.add(add)
463 repo.remove(remove) 466 repo.remove(remove)
464 467
465 def annotate(ui, repo, *pats, **opts): 468 def annotate(ui, repo, *pats, **opts):
466 """show changeset information per file line""" 469 """show changeset information per file line"""
670 673
671 def debugconfig(ui): 674 def debugconfig(ui):
672 """show combined config settings from all hgrc files""" 675 """show combined config settings from all hgrc files"""
673 try: 676 try:
674 repo = hg.repository(ui) 677 repo = hg.repository(ui)
675 except: pass 678 except hg.RepoError:
679 pass
676 for section, name, value in ui.walkconfig(): 680 for section, name, value in ui.walkconfig():
677 ui.write('%s.%s=%s\n' % (section, name, value)) 681 ui.write('%s.%s=%s\n' % (section, name, value))
678 682
679 def debugstate(ui, repo): 683 def debugstate(ui, repo):
680 """show the contents of the current dirstate""" 684 """show the contents of the current dirstate"""
716 ui.write("}\n") 720 ui.write("}\n")
717 721
718 def debugwalk(ui, repo, *pats, **opts): 722 def debugwalk(ui, repo, *pats, **opts):
719 """show how files match on given patterns""" 723 """show how files match on given patterns"""
720 items = list(walk(repo, pats, opts)) 724 items = list(walk(repo, pats, opts))
721 if not items: return 725 if not items:
726 return
722 fmt = '%%s %%-%ds %%-%ds %%s\n' % ( 727 fmt = '%%s %%-%ds %%-%ds %%s\n' % (
723 max([len(abs) for (src, abs, rel, exact) in items]), 728 max([len(abs) for (src, abs, rel, exact) in items]),
724 max([len(rel) for (src, abs, rel, exact) in items])) 729 max([len(rel) for (src, abs, rel, exact) in items]))
725 exactly = {True: 'exact', False: ''}
726 for src, abs, rel, exact in items: 730 for src, abs, rel, exact in items:
727 ui.write(fmt % (src, abs, rel, exactly[exact])) 731 ui.write(fmt % (src, abs, rel, exact and 'exact' or ''))
728 732
729 def diff(ui, repo, *pats, **opts): 733 def diff(ui, repo, *pats, **opts):
730 """diff working directory (or selected files)""" 734 """diff working directory (or selected files)"""
731 node1, node2 = None, None 735 node1, node2 = None, None
732 revs = [repo.lookup(x) for x in opts['rev']] 736 revs = [repo.lookup(x) for x in opts['rev']]
767 fp.write("# Parent %s\n" % hg.hex(other)) 771 fp.write("# Parent %s\n" % hg.hex(other))
768 fp.write(change[4].rstrip()) 772 fp.write(change[4].rstrip())
769 fp.write("\n\n") 773 fp.write("\n\n")
770 774
771 dodiff(fp, ui, repo, prev, node, text=opts['text']) 775 dodiff(fp, ui, repo, prev, node, text=opts['text'])
772 if fp != sys.stdout: fp.close() 776 if fp != sys.stdout:
777 fp.close()
773 778
774 def export(ui, repo, *changesets, **opts): 779 def export(ui, repo, *changesets, **opts):
775 """dump the header and diffs for one or more changesets""" 780 """dump the header and diffs for one or more changesets"""
776 if not changesets: 781 if not changesets:
777 raise util.Abort("export requires at least one changeset") 782 raise util.Abort("export requires at least one changeset")
788 """don't add the specified files on the next commit""" 793 """don't add the specified files on the next commit"""
789 forget = [] 794 forget = []
790 for src, abs, rel, exact in walk(repo, pats, opts): 795 for src, abs, rel, exact in walk(repo, pats, opts):
791 if repo.dirstate.state(abs) == 'a': 796 if repo.dirstate.state(abs) == 'a':
792 forget.append(abs) 797 forget.append(abs)
793 if not exact: ui.status('forgetting ', rel, '\n') 798 if not exact:
799 ui.status('forgetting ', rel, '\n')
794 repo.forget(forget) 800 repo.forget(forget)
795 801
796 def grep(ui, repo, pattern=None, *pats, **opts): 802 def grep(ui, repo, pattern=None, *pats, **opts):
797 """search for a pattern in specified files and revisions""" 803 """search for a pattern in specified files and revisions"""
798 if pattern is None: pattern = opts['regexp'] 804 if pattern is None:
799 if not pattern: raise util.Abort('no pattern to search for') 805 pattern = opts['regexp']
806 if not pattern:
807 raise util.Abort('no pattern to search for')
800 reflags = 0 808 reflags = 0
801 if opts['ignore_case']: reflags |= re.I 809 if opts['ignore_case']:
810 reflags |= re.I
802 regexp = re.compile(pattern, reflags) 811 regexp = re.compile(pattern, reflags)
803 sep, end = ':', '\n' 812 sep, end = ':', '\n'
804 if opts['null'] or opts['print0']: sep = end = '\0' 813 if opts['null'] or opts['print0']:
814 sep = end = '\0'
805 815
806 fcache = {} 816 fcache = {}
807 def getfile(fn): 817 def getfile(fn):
808 if fn not in fcache: 818 if fn not in fcache:
809 fcache[fn] = repo.file(fn) 819 fcache[fn] = repo.file(fn)
812 def matchlines(body): 822 def matchlines(body):
813 begin = 0 823 begin = 0
814 linenum = 0 824 linenum = 0
815 while True: 825 while True:
816 match = regexp.search(body, begin) 826 match = regexp.search(body, begin)
817 if not match: break 827 if not match:
828 break
818 mstart, mend = match.span() 829 mstart, mend = match.span()
819 linenum += body.count('\n', begin, mstart) + 1 830 linenum += body.count('\n', begin, mstart) + 1
820 lstart = body.rfind('\n', begin, mstart) + 1 or begin 831 lstart = body.rfind('\n', begin, mstart) + 1 or begin
821 lend = body.find('\n', mend) 832 lend = body.find('\n', mend)
822 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend] 833 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
826 def __init__(self, line, linenum, colstart, colend): 837 def __init__(self, line, linenum, colstart, colend):
827 self.line = line 838 self.line = line
828 self.linenum = linenum 839 self.linenum = linenum
829 self.colstart = colstart 840 self.colstart = colstart
830 self.colend = colend 841 self.colend = colend
831 def __eq__(self, other): return self.line == other.line 842 def __eq__(self, other):
832 def __hash__(self): return hash(self.line) 843 return self.line == other.line
844 def __hash__(self):
845 return hash(self.line)
833 846
834 matches = {} 847 matches = {}
835 def grepbody(fn, rev, body): 848 def grepbody(fn, rev, body):
836 matches[rev].setdefault(fn, {}) 849 matches[rev].setdefault(fn, {})
837 m = matches[rev][fn] 850 m = matches[rev][fn]
997 os.mkdir(dest) 1010 os.mkdir(dest)
998 hg.repository(ui, dest, create=1) 1011 hg.repository(ui, dest, create=1)
999 1012
1000 def locate(ui, repo, *pats, **opts): 1013 def locate(ui, repo, *pats, **opts):
1001 """locate files matching specific patterns""" 1014 """locate files matching specific patterns"""
1002 end = '\n' 1015 end = opts['print0'] and '\0' or '\n'
1003 if opts['print0']: end = '\0'
1004 1016
1005 for src, abs, rel, exact in walk(repo, pats, opts, '(?:.*/|)'): 1017 for src, abs, rel, exact in walk(repo, pats, opts, '(?:.*/|)'):
1006 if repo.dirstate.state(abs) == '?': continue 1018 if repo.dirstate.state(abs) == '?':
1019 continue
1007 if opts['fullpath']: 1020 if opts['fullpath']:
1008 ui.write(os.path.join(repo.root, abs), end) 1021 ui.write(os.path.join(repo.root, abs), end)
1009 else: 1022 else:
1010 ui.write(rel, end) 1023 ui.write(rel, end)
1011 1024
1019 self.hunk = {} 1032 self.hunk = {}
1020 def bump(self, rev): 1033 def bump(self, rev):
1021 self.rev = rev 1034 self.rev = rev
1022 self.hunk[rev] = [] 1035 self.hunk[rev] = []
1023 def note(self, *args): 1036 def note(self, *args):
1024 if self.verbose: self.write(*args) 1037 if self.verbose:
1038 self.write(*args)
1025 def status(self, *args): 1039 def status(self, *args):
1026 if not self.quiet: self.write(*args) 1040 if not self.quiet:
1041 self.write(*args)
1027 def write(self, *args): 1042 def write(self, *args):
1028 self.hunk[self.rev].append(args) 1043 self.hunk[self.rev].append(args)
1029 def __getattr__(self, key): 1044 def __getattr__(self, key):
1030 return getattr(self.ui, key) 1045 return getattr(self.ui, key)
1031 cwd = repo.getcwd() 1046 cwd = repo.getcwd()
1091 1106
1092 def paths(ui, search=None): 1107 def paths(ui, search=None):
1093 """show definition of symbolic path names""" 1108 """show definition of symbolic path names"""
1094 try: 1109 try:
1095 repo = hg.repository(ui=ui) 1110 repo = hg.repository(ui=ui)
1096 except: 1111 except hg.RepoError:
1097 pass 1112 pass
1098 1113
1099 if search: 1114 if search:
1100 for name, path in ui.configitems("paths"): 1115 for name, path in ui.configitems("paths"):
1101 if name == search: 1116 if name == search:
1518 "forget": 1533 "forget":
1519 (forget, 1534 (forget,
1520 [('I', 'include', [], 'include path in search'), 1535 [('I', 'include', [], 'include path in search'),
1521 ('X', 'exclude', [], 'exclude path from search')], 1536 ('X', 'exclude', [], 'exclude path from search')],
1522 "hg forget [OPTION]... FILE..."), 1537 "hg forget [OPTION]... FILE..."),
1523 "grep": (grep, 1538 "grep":
1524 [('0', 'print0', None, 'terminate file names with NUL'), 1539 (grep,
1525 ('I', 'include', [], 'include path in search'), 1540 [('0', 'print0', None, 'terminate file names with NUL'),
1526 ('X', 'exclude', [], 'include path in search'), 1541 ('I', 'include', [], 'include path in search'),
1527 ('Z', 'null', None, 'terminate file names with NUL'), 1542 ('X', 'exclude', [], 'include path in search'),
1528 ('a', 'all-revs', '', 'search all revs'), 1543 ('Z', 'null', None, 'terminate file names with NUL'),
1529 ('e', 'regexp', '', 'pattern to search for'), 1544 ('a', 'all-revs', '', 'search all revs'),
1530 ('f', 'full-path', None, 'print complete paths'), 1545 ('e', 'regexp', '', 'pattern to search for'),
1531 ('i', 'ignore-case', None, 'ignore case when matching'), 1546 ('f', 'full-path', None, 'print complete paths'),
1532 ('l', 'files-with-matches', None, 'print names of files with matches'), 1547 ('i', 'ignore-case', None, 'ignore case when matching'),
1533 ('n', 'line-number', '', 'print line numbers'), 1548 ('l', 'files-with-matches', None, 'print names of files with matches'),
1534 ('r', 'rev', [], 'search in revision rev'), 1549 ('n', 'line-number', '', 'print line numbers'),
1535 ('s', 'no-messages', None, 'do not print error messages'), 1550 ('r', 'rev', [], 'search in revision rev'),
1536 ('v', 'invert-match', None, 'select non-matching lines')], 1551 ('s', 'no-messages', None, 'do not print error messages'),
1537 "hg grep [options] [pat] [files]"), 1552 ('v', 'invert-match', None, 'select non-matching lines')],
1553 "hg grep [options] [pat] [files]"),
1538 "heads": 1554 "heads":
1539 (heads, 1555 (heads,
1540 [('b', 'branches', None, 'find branch info')], 1556 [('b', 'branches', None, 'find branch info')],
1541 'hg heads [-b]'), 1557 'hg heads [-b]'),
1542 "help": (help_, [], 'hg help [COMMAND]'), 1558 "help": (help_, [], 'hg help [COMMAND]'),
1652 ('', 'profile', None, 'profile'), 1668 ('', 'profile', None, 'profile'),
1653 ('', 'version', None, 'output version information and exit'), 1669 ('', 'version', None, 'output version information and exit'),
1654 ('h', 'help', None, 'display help and exit'), 1670 ('h', 'help', None, 'display help and exit'),
1655 ] 1671 ]
1656 1672
1657 norepo = "clone init version help debugconfig debugdata" + \ 1673 norepo = ("clone init version help debugconfig debugdata"
1658 " debugindex debugindexdot paths" 1674 " debugindex debugindexdot paths")
1659 1675
1660 def find(cmd): 1676 def find(cmd):
1661 for e in table.keys(): 1677 for e in table.keys():
1662 if re.match("(%s)$" % e, cmd): 1678 if re.match("(%s)$" % e, cmd):
1663 return e, table[e] 1679 return e, table[e]
1810 if hasattr(inst, "code"): 1826 if hasattr(inst, "code"):
1811 u.warn("abort: %s\n" % inst) 1827 u.warn("abort: %s\n" % inst)
1812 elif hasattr(inst, "reason"): 1828 elif hasattr(inst, "reason"):
1813 u.warn("abort: error: %s\n" % inst.reason[1]) 1829 u.warn("abort: error: %s\n" % inst.reason[1])
1814 elif hasattr(inst, "args") and inst[0] == errno.EPIPE: 1830 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
1815 if u.debugflag: u.warn("broken pipe\n") 1831 if u.debugflag:
1832 u.warn("broken pipe\n")
1816 else: 1833 else:
1817 raise 1834 raise
1818 except OSError, inst: 1835 except OSError, inst:
1819 if hasattr(inst, "filename"): 1836 if hasattr(inst, "filename"):
1820 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename)) 1837 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))