--- a/mercurial/match.py Thu Nov 22 17:25:49 2018 +0100
+++ b/mercurial/match.py Thu Nov 22 21:02:02 2018 +0100
@@ -1185,6 +1185,7 @@
return regex, lambda f: any(mf(f) for mf in matchfuncs)
MAX_RE_SIZE = 20000
+_BASE_SIZE = len('(?:)') - 1
def _joinregexes(regexps):
"""gather multiple regular expressions into a single one"""
@@ -1203,20 +1204,31 @@
OverflowError
"""
try:
- regex = _joinregexes([_regex(k, p, globsuffix)
- for (k, p, s) in kindpats])
- if len(regex) <= MAX_RE_SIZE:
- return regex, _rematcher(regex)
- # We're using a Python with a tiny regex engine and we
- # made it explode, so we'll divide the pattern list in two
- # until it works
- l = len(kindpats)
- if l < 2:
- # TODO: raise error.Abort here
- raise OverflowError
- regexa, a = _buildregexmatch(kindpats[:l//2], globsuffix)
- regexb, b = _buildregexmatch(kindpats[l//2:], globsuffix)
- return regex, lambda s: a(s) or b(s)
+ allgroups = []
+ regexps = [_regex(k, p, globsuffix) for (k, p, s) in kindpats]
+ fullregexp = _joinregexes(regexps)
+
+ startidx = 0
+ groupsize = _BASE_SIZE
+ for idx, r in enumerate(regexps):
+ piecesize = len(r)
+ if (piecesize + 4) > MAX_RE_SIZE:
+ raise OverflowError
+ elif (groupsize + 1 + piecesize) > MAX_RE_SIZE:
+ group = regexps[startidx:idx]
+ allgroups.append(_joinregexes(group))
+ startidx = idx
+ groupsize = _BASE_SIZE
+ groupsize += piecesize + 1
+
+ if startidx == 0:
+ func = _rematcher(fullregexp)
+ else:
+ group = regexps[startidx:]
+ allgroups.append(_joinregexes(group))
+ allmatchers = [_rematcher(g) for g in allgroups]
+ func = lambda s: any(m(s) for m in allmatchers)
+ return fullregexp, func
except re.error:
for k, p, s in kindpats:
try: