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)