Mercurial > hg-stable
changeset 14675:cfc89398f710
match: introduce basic fileset support
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sat, 18 Jun 2011 16:53:44 -0500 |
parents | 1c151b963254 |
children | e80fa502b8cf |
files | mercurial/match.py |
diffstat | 1 files changed, 33 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/match.py Sat Jun 18 16:52:51 2011 -0500 +++ b/mercurial/match.py Sat Jun 18 16:53:44 2011 -0500 @@ -6,9 +6,24 @@ # GNU General Public License version 2 or any later version. import re -import scmutil, util +import scmutil, util, fileset from i18n import _ +def _expandsets(pats, ctx): + '''convert set: patterns into a list of files in the given context''' + fset = set() + other = [] + + for kind, expr in pats: + if kind == 'set': + if not ctx: + raise util.Abort("fileset expression with no context") + s = fileset.getfileset(ctx, expr) + fset.update(s) + continue + other.append((kind, expr)) + return fset, other + class match(object): def __init__(self, root, cwd, patterns, include=[], exclude=[], default='glob', exact=False, auditor=None, ctx=None): @@ -30,9 +45,11 @@ 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs) 'relpath:<path>' - a path relative to cwd 'relre:<regexp>' - a regexp that needn't match the start of a name + 'set:<fileset>' - a fileset expression '<something>' - a pattern of the specified default type """ + self._ctx = None self._root = root self._cwd = cwd self._files = [] @@ -41,10 +58,10 @@ if include: pats = _normalize(include, 'glob', root, cwd, auditor) - self.includepat, im = _buildmatch(pats, '(?:/|$)') + self.includepat, im = _buildmatch(ctx, pats, '(?:/|$)') if exclude: pats = _normalize(exclude, 'glob', root, cwd, auditor) - self.excludepat, em = _buildmatch(pats, '(?:/|$)') + self.excludepat, em = _buildmatch(ctx, pats, '(?:/|$)') if exact: self._files = patterns pm = self.exact @@ -52,7 +69,7 @@ pats = _normalize(patterns, default, root, cwd, auditor) self._files = _roots(pats) self._anypats = self._anypats or _anypats(pats) - self.patternspat, pm = _buildmatch(pats, '$') + self.patternspat, pm = _buildmatch(ctx, pats, '$') if patterns or exact: if include: @@ -163,7 +180,7 @@ if ':' in pat: kind, val = pat.split(':', 1) if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre', - 'listfile', 'listfile0'): + 'listfile', 'listfile0', 'set'): return kind, val return default, pat @@ -241,7 +258,17 @@ return '.*' + name return _globre(name) + tail -def _buildmatch(pats, tail): +def _buildmatch(ctx, pats, tail): + fset, pats = _expandsets(pats, ctx) + if not pats: + return "", fset.__contains__ + + pat, mf = _buildregexmatch(pats, tail) + if fset: + return pat, lambda f: f in fset or mf(f) + return pat, mf + +def _buildregexmatch(pats, tail): """build a matching function from a set of patterns""" try: pat = '(?:%s)' % '|'.join([_regex(k, p, tail) for (k, p) in pats])