Show More
@@ -40,16 +40,24 b' def relpath(repo, args):' | |||||
40 | return args |
|
40 | return args | |
41 |
|
41 | |||
42 | def matchpats(cwd, pats = [], opts = {}, head = ''): |
|
42 | def matchpats(cwd, pats = [], opts = {}, head = ''): | |
43 | return util.matcher(cwd, pats, opts.get('include'), |
|
43 | return util.matcher(cwd, pats or ['.'], opts.get('include'), | |
44 | opts.get('exclude'), head) |
|
44 | opts.get('exclude'), head) | |
45 |
|
45 | |||
|
46 | def pathto(n1, n2): | |||
|
47 | '''return the relative path from one place to another''' | |||
|
48 | if not n1: return n2 | |||
|
49 | a, b = n1.split(os.sep), n2.split(os.sep) | |||
|
50 | a.reverse(), b.reverse() | |||
|
51 | while a and b and a[-1] == b[-1]: | |||
|
52 | a.pop(), b.pop() | |||
|
53 | b.reverse() | |||
|
54 | return os.sep.join((['..'] * len(a)) + b) | |||
|
55 | ||||
46 | def walk(repo, pats, opts, head = ''): |
|
56 | def walk(repo, pats, opts, head = ''): | |
47 | cwd = repo.getcwd() |
|
57 | cwd = repo.getcwd() | |
48 | c = 0 |
|
|||
49 | if cwd: c = len(cwd) + 1 |
|
|||
50 | files, matchfn = matchpats(cwd, pats, opts, head) |
|
58 | files, matchfn = matchpats(cwd, pats, opts, head) | |
51 | for src, fn in repo.walk(files = files, match = matchfn): |
|
59 | for src, fn in repo.walk(files = files, match = matchfn): | |
52 |
yield src, fn, fn |
|
60 | yield src, fn, pathto(cwd, fn) | |
53 |
|
61 | |||
54 | revrangesep = ':' |
|
62 | revrangesep = ':' | |
55 |
|
63 | |||
@@ -565,6 +573,11 b' def debugindexdot(ui, file_):' | |||||
565 | ui.write("\t%d -> %d\n" % (r.rev(e[5]), i)) |
|
573 | ui.write("\t%d -> %d\n" % (r.rev(e[5]), i)) | |
566 | ui.write("}\n") |
|
574 | ui.write("}\n") | |
567 |
|
575 | |||
|
576 | def debugwalk(ui, repo, *pats, **opts): | |||
|
577 | items = list(walk(repo, pats, opts)) | |||
|
578 | fmt = '%%s %%-%ds %%s' % max([len(abs) for (src, abs, rel) in items]) | |||
|
579 | for i in items: print fmt % i | |||
|
580 | ||||
568 | def diff(ui, repo, *pats, **opts): |
|
581 | def diff(ui, repo, *pats, **opts): | |
569 | """diff working directory (or selected files)""" |
|
582 | """diff working directory (or selected files)""" | |
570 | revs = [] |
|
583 | revs = [] | |
@@ -1015,9 +1028,10 b' def status(ui, repo, *pats, **opts):' | |||||
1015 | R = removed |
|
1028 | R = removed | |
1016 | ? = not tracked''' |
|
1029 | ? = not tracked''' | |
1017 |
|
1030 | |||
1018 | files, matchfn = matchpats(repo.getcwd(), pats, opts) |
|
1031 | cwd = repo.getcwd() | |
|
1032 | files, matchfn = matchpats(cwd, pats, opts) | |||
1019 | (c, a, d, u) = repo.changes(files = files, match = matchfn) |
|
1033 | (c, a, d, u) = repo.changes(files = files, match = matchfn) | |
1020 |
(c, a, d, u) = map(lambda x: |
|
1034 | (c, a, d, u) = [map(lambda x: pathto(cwd, x), n) for n in c, a, d, u] | |
1021 |
|
1035 | |||
1022 | for f in c: |
|
1036 | for f in c: | |
1023 | ui.write("M ", f, "\n") |
|
1037 | ui.write("M ", f, "\n") | |
@@ -1160,6 +1174,10 b' table = {' | |||||
1160 | "debugstate": (debugstate, [], 'debugstate'), |
|
1174 | "debugstate": (debugstate, [], 'debugstate'), | |
1161 | "debugindex": (debugindex, [], 'debugindex FILE'), |
|
1175 | "debugindex": (debugindex, [], 'debugindex FILE'), | |
1162 | "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'), |
|
1176 | "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'), | |
|
1177 | "debugwalk": (debugwalk, | |||
|
1178 | [('I', 'include', [], 'include path in search'), | |||
|
1179 | ('X', 'exclude', [], 'exclude path from search')], | |||
|
1180 | 'debugwalk [OPTIONS]... [FILE]...'), | |||
1163 | "^diff": |
|
1181 | "^diff": | |
1164 | (diff, |
|
1182 | (diff, | |
1165 | [('r', 'rev', [], 'revision'), |
|
1183 | [('r', 'rev', [], 'revision'), |
@@ -446,11 +446,12 b' class dirstate:' | |||||
446 | if os.path.isdir(f): |
|
446 | if os.path.isdir(f): | |
447 | for dir, subdirs, fl in os.walk(f): |
|
447 | for dir, subdirs, fl in os.walk(f): | |
448 | d = dir[len(self.root) + 1:] |
|
448 | d = dir[len(self.root) + 1:] | |
449 |
|
|
449 | nd = os.path.normpath(d) | |
|
450 | if nd == '.hg': | |||
450 | subdirs[:] = [] |
|
451 | subdirs[:] = [] | |
451 | continue |
|
452 | continue | |
452 | for sd in subdirs: |
|
453 | for sd in subdirs: | |
453 | ds = os.path.join(d, sd +'/') |
|
454 | ds = os.path.join(nd, sd +'/') | |
454 | if self.ignore(ds) or not match(ds): |
|
455 | if self.ignore(ds) or not match(ds): | |
455 | subdirs.remove(sd) |
|
456 | subdirs.remove(sd) | |
456 | for fn in fl: |
|
457 | for fn in fl: | |
@@ -466,6 +467,7 b' class dirstate:' | |||||
466 | # not in .hgignore |
|
467 | # not in .hgignore | |
467 |
|
468 | |||
468 | for src, fn in util.unique(traverse()): |
|
469 | for src, fn in util.unique(traverse()): | |
|
470 | fn = os.path.normpath(fn) | |||
469 | if fn in dc: |
|
471 | if fn in dc: | |
470 | del dc[fn] |
|
472 | del dc[fn] | |
471 | elif self.ignore(fn): |
|
473 | elif self.ignore(fn): | |
@@ -868,7 +870,7 b' class localrepository:' | |||||
868 | def walk(self, node = None, files = [], match = util.always): |
|
870 | def walk(self, node = None, files = [], match = util.always): | |
869 | if node: |
|
871 | if node: | |
870 | for fn in self.manifest.read(self.changelog.read(node)[0]): |
|
872 | for fn in self.manifest.read(self.changelog.read(node)[0]): | |
871 | yield 'm', fn |
|
873 | if match(fn): yield 'm', fn | |
872 | else: |
|
874 | else: | |
873 | for src, fn in self.dirstate.walk(files, match): |
|
875 | for src, fn in self.dirstate.walk(files, match): | |
874 | yield src, fn |
|
876 | yield src, fn |
@@ -69,24 +69,27 b" def globre(pat, head = '^', tail = '$'):" | |||||
69 | _globchars = {'[': 1, '{': 1, '*': 1, '?': 1} |
|
69 | _globchars = {'[': 1, '{': 1, '*': 1, '?': 1} | |
70 |
|
70 | |||
71 | def matcher(cwd, names, inc, exc, head = ''): |
|
71 | def matcher(cwd, names, inc, exc, head = ''): | |
72 |
def pat |
|
72 | def patkind(name): | |
73 | for prefix in 're:', 'glob:', 'path:': |
|
73 | for prefix in 're:', 'glob:', 'path:': | |
74 |
if name.startswith(prefix): return |
|
74 | if name.startswith(prefix): return name.split(':', 1) | |
75 | for c in name: |
|
75 | for c in name: | |
76 |
if c in _globchars: return |
|
76 | if c in _globchars: return 'glob', name | |
|
77 | return 'relpath', name | |||
|
78 | ||||
|
79 | cwdsep = cwd + os.sep | |||
77 |
|
80 | |||
78 | def regex(name, tail): |
|
81 | def regex(name, tail): | |
79 | '''convert a pattern into a regular expression''' |
|
82 | '''convert a pattern into a regular expression''' | |
80 | if name.startswith('re:'): |
|
83 | kind, name = patkind(name) | |
81 | return name[3:] |
|
84 | if kind == 're': | |
82 | elif name.startswith('path:'): |
|
85 | return name | |
83 | return '^' + re.escape(name[5:]) + '$' |
|
86 | elif kind == 'path': | |
84 | elif name.startswith('glob:'): |
|
87 | return '^' + re.escape(name) + '$' | |
85 | return head + globre(name[5:], '', tail) |
|
88 | if cwd: name = os.path.join(cwdsep, name) | |
|
89 | name = os.path.normpath(name) | |||
|
90 | if name == '.': name = '**' | |||
86 | return head + globre(name, '', tail) |
|
91 | return head + globre(name, '', tail) | |
87 |
|
92 | |||
88 | cwdsep = cwd + os.sep |
|
|||
89 |
|
||||
90 | def under(fn): |
|
93 | def under(fn): | |
91 | """check if fn is under our cwd""" |
|
94 | """check if fn is under our cwd""" | |
92 | return not cwd or fn.startswith(cwdsep) |
|
95 | return not cwd or fn.startswith(cwdsep) | |
@@ -95,22 +98,28 b' def matcher(cwd, names, inc, exc, head =' | |||||
95 | """build a matching function from a set of patterns""" |
|
98 | """build a matching function from a set of patterns""" | |
96 | if pats: |
|
99 | if pats: | |
97 | pat = '(?:%s)' % '|'.join([regex(p, tail) for p in pats]) |
|
100 | pat = '(?:%s)' % '|'.join([regex(p, tail) for p in pats]) | |
98 | if cwd: |
|
|||
99 | pat = re.escape(cwdsep) + pat |
|
|||
100 | return re.compile(pat).match |
|
101 | return re.compile(pat).match | |
101 |
|
102 | |||
102 | pats = filter(patlike, names) |
|
103 | def globprefix(pat): | |
103 | files = [n for n in names if not patlike(n)] |
|
104 | '''return the non-glob prefix of a path, e.g. foo/* -> foo''' | |
104 | if pats: plain = [] |
|
105 | root = [] | |
105 | elif cwd: plain = [cwdsep + f for f in files] |
|
106 | for p in pat.split(os.sep): | |
106 | else: plain = files |
|
107 | if patkind(p)[0] == 'glob': break | |
|
108 | root.append(p) | |||
|
109 | return os.sep.join(root) | |||
|
110 | ||||
|
111 | patkinds = map(patkind, names) | |||
|
112 | pats = [name for (kind, name) in patkinds if kind != 'relpath'] | |||
|
113 | files = [name for (kind, name) in patkinds if kind == 'relpath'] | |||
|
114 | roots = filter(None, map(globprefix, pats)) + files | |||
|
115 | if cwd: roots = [cwdsep + r for r in roots] | |||
107 |
|
116 | |||
108 | patmatch = matchfn(pats, '$') |
|
117 | patmatch = matchfn(pats, '$') or always | |
109 | filematch = matchfn(files, '(?:/|$)') |
|
118 | filematch = matchfn(files, '(?:/|$)') or always | |
110 |
incmatch = matchfn(inc, '(?:/|$)') or |
|
119 | incmatch = matchfn(inc, '(?:/|$)') or always | |
111 | excmatch = matchfn(exc, '(?:/|$)') or (lambda fn: False) |
|
120 | excmatch = matchfn(exc, '(?:/|$)') or (lambda fn: False) | |
112 |
|
121 | |||
113 |
return |
|
122 | return roots, lambda fn: (incmatch(fn) and not excmatch(fn) and | |
114 | (fn.endswith('/') or |
|
123 | (fn.endswith('/') or | |
115 | (not pats and not files) or |
|
124 | (not pats and not files) or | |
116 | (pats and patmatch(fn)) or |
|
125 | (pats and patmatch(fn)) or |
General Comments 0
You need to be logged in to leave comments.
Login now