# HG changeset patch # User Bryan O'Sullivan # Date 1177437205 25200 # Node ID d7ad1e42a3681dab3811d21f75aff2d9b4215a3b # Parent 6af107c742bf33f306c57c1a0b529b99af750e43 util._matcher: speed up regexp matching. In 4babaa52badf, Benoit made a change that substantially slows matching when a big .hgignore file is in play, because it calls into the regexp matching engine potentially hundreds of times per file to be matched. I've partly rolled back his change, so that we only call into the matcher once per file, but preserved the ability to report a meaningful error message if there's a syntax error in the regexp. diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -469,22 +469,20 @@ def _matcher(canonroot, cwd, names, inc, """build a matching function from a set of patterns""" if not pats: return - matches = [] - for k, p in pats: - try: - pat = '(?:%s)' % regex(k, p, tail) - matches.append(re.compile(pat).match) - except re.error: - if src: raise Abort("%s: invalid pattern (%s): %s" % (src, k, p)) - else: raise Abort("invalid pattern (%s): %s" % (k, p)) - - def buildfn(text): - for m in matches: - r = m(text) - if r: - return r - - return buildfn + try: + pat = '(?:%s)' % '|'.join([regex(k, p, tail) for (k, p) in pats]) + return re.compile(pat).match + except re.error: + for k, p in pats: + try: + re.compile('(?:%s)' % regex(k, p, tail)) + except re.error: + if src: + raise Abort("%s: invalid pattern (%s): %s" % + (src, k, p)) + else: + raise Abort("invalid pattern (%s): %s" % (k, p)) + raise Abort("invalid pattern") def globprefix(pat): '''return the non-glob prefix of a path, e.g. foo/* -> foo'''