# HG changeset patch # User Martin von Zweigbergk # Date 2014-09-19 20:49:58 # Node ID ca709785caf29a092b0bfe35c31ef1cd1e54beaa # Parent 6b6da715cb963db821bdc88e9aa9316994568e9e match: simplify brittle predicate construction In match.__init__(), we create the matchfn predicate by and-ing together the individual predicates for includes, excludes (negated) and patterns. Instead of the current set of nested if/else blocks, we can simplify by adding the predicates to a list and defining the overall predicate in a generic way based on the components. We can still optimize it for the 0-length and 1-length cases. This way, there is no combinatorial explosion to deal with if new component predicates are added, and there is less risk of getting the overall predicate wrong. diff --git a/mercurial/match.py b/mercurial/match.py --- a/mercurial/match.py +++ b/mercurial/match.py @@ -66,47 +66,39 @@ class match(object): self._ctx = ctx self._always = False + matchfns = [] if include: kindpats = _normalize(include, 'glob', root, cwd, auditor) self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)') + matchfns.append(im) if exclude: kindpats = _normalize(exclude, 'glob', root, cwd, auditor) self.excludepat, em = _buildmatch(ctx, kindpats, '(?:/|$)') + matchfns.append(lambda f: not em(f)) if exact: if isinstance(patterns, list): self._files = patterns else: self._files = list(patterns) - pm = self.exact + matchfns.append(self.exact) elif patterns: kindpats = _normalize(patterns, default, root, cwd, auditor) self._files = _roots(kindpats) self._anypats = self._anypats or _anypats(kindpats) self.patternspat, pm = _buildmatch(ctx, kindpats, '$') + matchfns.append(pm) - if patterns or exact: - if include: - if exclude: - m = lambda f: im(f) and not em(f) and pm(f) - else: - m = lambda f: im(f) and pm(f) - else: - if exclude: - m = lambda f: not em(f) and pm(f) - else: - m = pm + if not matchfns: + m = util.always + self._always = True + elif len(matchfns) == 1: + m = matchfns[0] else: - if include: - if exclude: - m = lambda f: im(f) and not em(f) - else: - m = im - else: - if exclude: - m = lambda f: not em(f) - else: - m = lambda f: True - self._always = True + def m(f): + for matchfn in matchfns: + if not matchfn(f): + return False + return True self.matchfn = m self._fmap = set(self._files)