Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/fileset.py @ 14677:2a758ffc821e
fileset: add support for file status predicates
This forcibly walks the tree looking for unknown and ignored files,
which is suboptimal. A better approach would scan the tree first to
find required status components and skip the status check entirely if
it's unused.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sat, 18 Jun 2011 16:53:49 -0500 |
parents | e80fa502b8cf |
children | 5ef7b87530f6 |
comparison
equal
deleted
inserted
replaced
14676:e80fa502b8cf | 14677:2a758ffc821e |
---|---|
108 return [r for r in mctx.subset if r not in s] | 108 return [r for r in mctx.subset if r not in s] |
109 | 109 |
110 def listset(mctx, a, b): | 110 def listset(mctx, a, b): |
111 raise error.ParseError(_("can't use a list in this context")) | 111 raise error.ParseError(_("can't use a list in this context")) |
112 | 112 |
113 def modified(mctx, x): | |
114 getargs(x, 0, 0, _("modified takes no arguments")) | |
115 s = mctx.status()[0] | |
116 return [f for f in mctx.subset if f in s] | |
117 | |
118 def added(mctx, x): | |
119 getargs(x, 0, 0, _("added takes no arguments")) | |
120 s = mctx.status()[1] | |
121 return [f for f in mctx.subset if f in s] | |
122 | |
123 def removed(mctx, x): | |
124 getargs(x, 0, 0, _("removed takes no arguments")) | |
125 s = mctx.status()[2] | |
126 return [f for f in mctx.subset if f in s] | |
127 | |
128 def deleted(mctx, x): | |
129 getargs(x, 0, 0, _("deleted takes no arguments")) | |
130 s = mctx.status()[3] | |
131 return [f for f in mctx.subset if f in s] | |
132 | |
133 def unknown(mctx, x): | |
134 getargs(x, 0, 0, _("unknown takes no arguments")) | |
135 s = mctx.status()[4] | |
136 return [f for f in mctx.subset if f in s] | |
137 | |
138 def ignored(mctx, x): | |
139 getargs(x, 0, 0, _("ignored takes no arguments")) | |
140 s = mctx.status()[5] | |
141 return [f for f in mctx.subset if f in s] | |
142 | |
143 def clean(mctx, x): | |
144 getargs(x, 0, 0, _("clean takes no arguments")) | |
145 s = mctx.status()[6] | |
146 return [f for f in mctx.subset if f in s] | |
147 | |
113 def func(mctx, a, b): | 148 def func(mctx, a, b): |
114 if a[0] == 'symbol' and a[1] in symbols: | 149 if a[0] == 'symbol' and a[1] in symbols: |
115 return symbols[a[1]](mctx, b) | 150 return symbols[a[1]](mctx, b) |
116 raise error.ParseError(_("not a function: %s") % a[1]) | 151 raise error.ParseError(_("not a function: %s") % a[1]) |
117 | 152 |
139 def symlink(mctx, x): | 174 def symlink(mctx, x): |
140 getargs(x, 0, 0, _("symlink takes no arguments")) | 175 getargs(x, 0, 0, _("symlink takes no arguments")) |
141 return [f for f in mctx.subset if mctx.ctx.flags(f) == 'l'] | 176 return [f for f in mctx.subset if mctx.ctx.flags(f) == 'l'] |
142 | 177 |
143 symbols = { | 178 symbols = { |
179 'added': added, | |
144 'binary': binary, | 180 'binary': binary, |
181 'clean': clean, | |
182 'deleted': deleted, | |
145 'exec': exec_, | 183 'exec': exec_, |
184 'ignored': ignored, | |
185 'modified': modified, | |
186 'removed': removed, | |
146 'symlink': symlink, | 187 'symlink': symlink, |
188 'unknown': unknown, | |
147 } | 189 } |
148 | 190 |
149 methods = { | 191 methods = { |
150 'string': stringset, | 192 'string': stringset, |
151 'symbol': stringset, | 193 'symbol': stringset, |
156 'not': notset, | 198 'not': notset, |
157 'func': func, | 199 'func': func, |
158 } | 200 } |
159 | 201 |
160 class matchctx(object): | 202 class matchctx(object): |
161 def __init__(self, ctx, subset=None): | 203 def __init__(self, ctx, subset=None, status=None): |
162 self.ctx = ctx | 204 self.ctx = ctx |
163 self.subset = subset | 205 self.subset = subset |
206 self._status = status | |
207 if status is None: | |
208 # desperately wants optimizing | |
209 r = self.ctx._repo | |
210 self._status = r.status(self.ctx.p1(), self.ctx, | |
211 unknown=True, ignored=True, clean=True) | |
164 if subset is None: | 212 if subset is None: |
165 self.subset = ctx.walk(self.matcher([])) # optimize this later | 213 self.subset = [] |
214 for c in self._status: | |
215 self.subset.extend(c) | |
216 def status(self): | |
217 if not self._status: | |
218 r = self.ctx._repo | |
219 # also wants optimizing | |
220 self._status = r.status(self.ctx.p1(), self.ctx, | |
221 unknown=True, ignored=True, clean=True) | |
222 return self._status | |
166 def matcher(self, patterns): | 223 def matcher(self, patterns): |
167 return self.ctx.match(patterns) | 224 return self.ctx.match(patterns) |
168 def filter(self, files): | 225 def filter(self, files): |
169 return [f for f in files if f in self.subset] | 226 return [f for f in files if f in self.subset] |
170 def narrow(self, files): | 227 def narrow(self, files): |
171 return matchctx(self.ctx, self.filter(files)) | 228 return matchctx(self.ctx, self.filter(files), self._status) |
172 | 229 |
173 def getfileset(ctx, expr): | 230 def getfileset(ctx, expr): |
174 tree, pos = parse(expr) | 231 tree, pos = parse(expr) |
175 if (pos != len(expr)): | 232 if (pos != len(expr)): |
176 raise error.ParseError("invalid token", pos) | 233 raise error.ParseError("invalid token", pos) |