Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/fileset.py @ 14678:5ef7b87530f6
fileset: prescan parse tree to optimize status usage
We only call status if needed to avoid walking the working directory
or comparing manifests.
Similarly, we scan for whether unknown or ignored files are mentioned
so we can include them.
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sat, 18 Jun 2011 16:53:49 -0500 |
parents | 2a758ffc821e |
children | e141e1cee0cc |
comparison
equal
deleted
inserted
replaced
14677:2a758ffc821e | 14678:5ef7b87530f6 |
---|---|
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) |