Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/commands.py @ 724:1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
They use a walk function that abstracts out the irritating details, so
that there's a higher likelihood of commands behaving uniformly.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Mon, 18 Jul 2005 06:54:21 -0800 |
parents | 9e0f3ba4a9c2 |
children | c6b912f8b5b2 |
comparison
equal
deleted
inserted
replaced
723:9e0f3ba4a9c2 | 724:1c0c413cccdd |
---|---|
33 cwd = repo.getcwd() | 33 cwd = repo.getcwd() |
34 if cwd: | 34 if cwd: |
35 return [util.pconvert(os.path.normpath(os.path.join(cwd, x))) | 35 return [util.pconvert(os.path.normpath(os.path.join(cwd, x))) |
36 for x in args] | 36 for x in args] |
37 return args | 37 return args |
38 | |
39 def matchpats(ui, cwd, pats = [], opts = {}): | |
40 head = '' | |
41 if opts.get('rootless'): head = '(?:.*/|)' | |
42 def reify(name, tail): | |
43 if name.startswith('re:'): | |
44 return name[3:] | |
45 elif name.startswith('glob:'): | |
46 return head + util.globre(name[5:], '', tail) | |
47 elif name.startswith('path:'): | |
48 return '^' + re.escape(name[5:]) + '$' | |
49 return head + util.globre(name, '', tail) | |
50 cwdsep = cwd + os.sep | |
51 def under(fn): | |
52 if not cwd or fn.startswith(cwdsep): return True | |
53 def matchfn(pats, tail, ifempty = util.always): | |
54 if not pats: return ifempty | |
55 pat = '(?:%s)' % '|'.join([reify(p, tail) for p in pats]) | |
56 if cwd: pat = re.escape(cwd + os.sep) + pat | |
57 ui.debug('regexp: %s\n' % pat) | |
58 return re.compile(pat).match | |
59 patmatch = matchfn(pats, '$') | |
60 incmatch = matchfn(opts.get('include'), '(?:/|$)', under) | |
61 excmatch = matchfn(opts.get('exclude'), '(?:/|$)', util.never) | |
62 return lambda fn: (incmatch(fn) and not excmatch(fn) and | |
63 (fn.endswith('/') or patmatch(fn))) | |
64 | |
65 def walk(repo, pats, opts): | |
66 cwd = repo.getcwd() | |
67 if cwd: c = len(cwd) + 1 | |
68 for fn in repo.walk(match = matchpats(repo.ui, cwd, pats, opts)): | |
69 if cwd: yield fn, fn[c:] | |
70 else: yield fn, fn | |
38 | 71 |
39 revrangesep = ':' | 72 revrangesep = ':' |
40 | 73 |
41 def revrange(ui, repo, revs, revlog=None): | 74 def revrange(ui, repo, revs, revlog=None): |
42 if revlog is None: | 75 if revlog is None: |
286 for f in fns: | 319 for f in fns: |
287 ui.write(' %-*s %s\n' % (m, f, h[f])) | 320 ui.write(' %-*s %s\n' % (m, f, h[f])) |
288 | 321 |
289 # Commands start here, listed alphabetically | 322 # Commands start here, listed alphabetically |
290 | 323 |
291 def add(ui, repo, file1, *files): | 324 def add(ui, repo, *pats, **opts): |
292 '''add the specified files on the next commit''' | 325 '''add the specified files on the next commit''' |
293 repo.add(relpath(repo, (file1,) + files)) | 326 names = [] |
327 q = dict(zip(pats, pats)) | |
328 for abs, rel in walk(repo, pats, opts): | |
329 if rel in q or abs in q: | |
330 names.append(abs) | |
331 elif repo.dirstate.state(abs) == '?': | |
332 ui.status('adding %s\n' % rel) | |
333 names.append(abs) | |
334 repo.add(names) | |
294 | 335 |
295 def addremove(ui, repo, *files): | 336 def addremove(ui, repo, *files): |
296 """add all new files, delete all missing files""" | 337 """add all new files, delete all missing files""" |
297 if files: | 338 if files: |
298 files = relpath(repo, files) | 339 files = relpath(repo, files) |
667 sys.exit(1) | 708 sys.exit(1) |
668 hg.repository(ui, ".", create=1) | 709 hg.repository(ui, ".", create=1) |
669 | 710 |
670 def locate(ui, repo, *pats, **opts): | 711 def locate(ui, repo, *pats, **opts): |
671 """locate files matching specific patterns""" | 712 """locate files matching specific patterns""" |
672 if [p for p in pats if os.sep in p]: | 713 if opts['print0']: end = '\0' |
673 ui.warn("error: patterns may not contain '%s'\n" % os.sep) | 714 else: end = '\n' |
674 ui.warn("use '-i <dir>' instead\n") | 715 opts['rootless'] = True |
675 sys.exit(1) | 716 for abs, rel in walk(repo, pats, opts): |
676 def compile(pats, head='^', tail=os.sep, on_empty=True): | 717 if repo.dirstate.state(abs) == '?': continue |
677 if not pats: | |
678 class c: | |
679 def match(self, x): | |
680 return on_empty | |
681 return c() | |
682 fnpats = [fnmatch.translate(os.path.normpath(os.path.normcase(p)))[:-1] | |
683 for p in pats] | |
684 regexp = r'%s(?:%s)%s' % (head, '|'.join(fnpats), tail) | |
685 return re.compile(regexp) | |
686 exclude = compile(opts['exclude'], on_empty=False) | |
687 include = compile(opts['include']) | |
688 pat = compile(pats, head='', tail='$') | |
689 end = opts['print0'] and '\0' or '\n' | |
690 if opts['rev']: | |
691 node = repo.manifest.lookup(opts['rev']) | |
692 else: | |
693 node = repo.manifest.tip() | |
694 manifest = repo.manifest.read(node) | |
695 cwd = repo.getcwd() | |
696 cwd_plus = cwd and (cwd + os.sep) | |
697 found = [] | |
698 for f in manifest: | |
699 f = os.path.normcase(f) | |
700 if exclude.match(f) or not(include.match(f) and | |
701 f.startswith(cwd_plus) and | |
702 pat.match(os.path.basename(f))): | |
703 continue | |
704 if opts['fullpath']: | 718 if opts['fullpath']: |
705 f = os.path.join(repo.root, f) | 719 ui.write(os.path.join(repo.root, abs), end) |
706 elif cwd: | 720 else: |
707 f = f[len(cwd_plus):] | 721 ui.write(rel, end) |
708 found.append(f) | |
709 found.sort() | |
710 for f in found: | |
711 ui.write(f, end) | |
712 | 722 |
713 def log(ui, repo, f=None, **opts): | 723 def log(ui, repo, f=None, **opts): |
714 """show the revision history of the repository or a single file""" | 724 """show the revision history of the repository or a single file""" |
715 if f: | 725 if f: |
716 files = relpath(repo, [f]) | 726 files = relpath(repo, [f]) |
1085 return repo.verify() | 1095 return repo.verify() |
1086 | 1096 |
1087 # Command options and aliases are listed here, alphabetically | 1097 # Command options and aliases are listed here, alphabetically |
1088 | 1098 |
1089 table = { | 1099 table = { |
1090 "^add": (add, [], "hg add [files]"), | 1100 "^add": (add, |
1101 [('I', 'include', [], 'include path in search'), | |
1102 ('X', 'exclude', [], 'exclude path from search')], | |
1103 "hg add [options] [files]"), | |
1091 "addremove": (addremove, [], "hg addremove [files]"), | 1104 "addremove": (addremove, [], "hg addremove [files]"), |
1092 "^annotate": | 1105 "^annotate": |
1093 (annotate, | 1106 (annotate, |
1094 [('r', 'revision', '', 'revision'), | 1107 [('r', 'revision', '', 'revision'), |
1095 ('u', 'user', None, 'show user'), | 1108 ('u', 'user', None, 'show user'), |
1137 "^init": (init, [], 'hg init'), | 1150 "^init": (init, [], 'hg init'), |
1138 "locate": | 1151 "locate": |
1139 (locate, | 1152 (locate, |
1140 [('0', 'print0', None, 'end records with NUL'), | 1153 [('0', 'print0', None, 'end records with NUL'), |
1141 ('f', 'fullpath', None, 'print complete paths'), | 1154 ('f', 'fullpath', None, 'print complete paths'), |
1142 ('i', 'include', [], 'include path in search'), | 1155 ('I', 'include', [], 'include path in search'), |
1143 ('r', 'rev', '', 'revision'), | 1156 ('r', 'rev', '', 'revision'), |
1144 ('x', 'exclude', [], 'exclude path from search')], | 1157 ('X', 'exclude', [], 'exclude path from search')], |
1145 'hg locate [options] [files]'), | 1158 'hg locate [options] [files]'), |
1146 "^log|history": | 1159 "^log|history": |
1147 (log, | 1160 (log, |
1148 [('r', 'rev', [], 'revision'), | 1161 [('r', 'rev', [], 'revision'), |
1149 ('p', 'patch', None, 'show patch')], | 1162 ('p', 'patch', None, 'show patch')], |