202 class matchctx(object): |
202 class matchctx(object): |
203 def __init__(self, ctx, subset=None, status=None): |
203 def __init__(self, ctx, subset=None, status=None): |
204 self.ctx = ctx |
204 self.ctx = ctx |
205 self.subset = subset |
205 self.subset = subset |
206 self._status = status |
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) |
|
212 if subset is None: |
|
213 self.subset = [] |
|
214 for c in self._status: |
|
215 self.subset.extend(c) |
|
216 def status(self): |
207 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 |
208 return self._status |
223 def matcher(self, patterns): |
209 def matcher(self, patterns): |
224 return self.ctx.match(patterns) |
210 return self.ctx.match(patterns) |
225 def filter(self, files): |
211 def filter(self, files): |
226 return [f for f in files if f in self.subset] |
212 return [f for f in files if f in self.subset] |
227 def narrow(self, files): |
213 def narrow(self, files): |
228 return matchctx(self.ctx, self.filter(files), self._status) |
214 return matchctx(self.ctx, self.filter(files), self._status) |
229 |
215 |
|
216 def _intree(funcs, tree): |
|
217 if isinstance(tree, tuple): |
|
218 if tree[0] == 'func' and tree[1][0] == 'symbol': |
|
219 if tree[1][1] in funcs: |
|
220 return True |
|
221 for s in tree[1:]: |
|
222 if _intree(funcs, s): |
|
223 return True |
|
224 return False |
|
225 |
230 def getfileset(ctx, expr): |
226 def getfileset(ctx, expr): |
231 tree, pos = parse(expr) |
227 tree, pos = parse(expr) |
232 if (pos != len(expr)): |
228 if (pos != len(expr)): |
233 raise error.ParseError("invalid token", pos) |
229 raise error.ParseError("invalid token", pos) |
234 return getset(matchctx(ctx), tree) |
230 |
|
231 # do we need status info? |
|
232 if _intree(['modified', 'added', 'removed', 'deleted', |
|
233 'unknown', 'ignored', 'clean'], tree): |
|
234 unknown = _intree(['unknown'], tree) |
|
235 ignored = _intree(['ignored'], tree) |
|
236 |
|
237 r = ctx._repo |
|
238 status = r.status(ctx.p1(), ctx, |
|
239 unknown=unknown, ignored=ignored, clean=True) |
|
240 subset = [] |
|
241 for c in status: |
|
242 subset.extend(c) |
|
243 else: |
|
244 status = None |
|
245 subset = ctx.walk(ctx.match([])) |
|
246 |
|
247 return getset(matchctx(ctx, subset, status), tree) |