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')], |