24 def _expandsets(kindpats, ctx, listsubrepos): |
24 def _expandsets(kindpats, ctx, listsubrepos): |
25 '''Returns the kindpats list with the 'set' patterns expanded.''' |
25 '''Returns the kindpats list with the 'set' patterns expanded.''' |
26 fset = set() |
26 fset = set() |
27 other = [] |
27 other = [] |
28 |
28 |
29 for kind, pat in kindpats: |
29 for kind, pat, source in kindpats: |
30 if kind == 'set': |
30 if kind == 'set': |
31 if not ctx: |
31 if not ctx: |
32 raise util.Abort("fileset expression with no context") |
32 raise util.Abort("fileset expression with no context") |
33 s = ctx.getfileset(pat) |
33 s = ctx.getfileset(pat) |
34 fset.update(s) |
34 fset.update(s) |
37 for subpath in ctx.substate: |
37 for subpath in ctx.substate: |
38 s = ctx.sub(subpath).getfileset(pat) |
38 s = ctx.sub(subpath).getfileset(pat) |
39 fset.update(subpath + '/' + f for f in s) |
39 fset.update(subpath + '/' + f for f in s) |
40 |
40 |
41 continue |
41 continue |
42 other.append((kind, pat)) |
42 other.append((kind, pat, source)) |
43 return fset, other |
43 return fset, other |
44 |
44 |
45 def _kindpatsalwaysmatch(kindpats): |
45 def _kindpatsalwaysmatch(kindpats): |
46 """"Checks whether the kindspats match everything, as e.g. |
46 """"Checks whether the kindspats match everything, as e.g. |
47 'relpath:.' does. |
47 'relpath:.' does. |
48 """ |
48 """ |
49 for kind, pat in kindpats: |
49 for kind, pat, source in kindpats: |
50 if pat != '' or kind not in ['relpath', 'glob']: |
50 if pat != '' or kind not in ['relpath', 'glob']: |
51 return False |
51 return False |
52 return True |
52 return True |
53 |
53 |
54 class match(object): |
54 class match(object): |
220 else: |
220 else: |
221 files = files.splitlines() |
221 files = files.splitlines() |
222 files = [f for f in files if f] |
222 files = [f for f in files if f] |
223 except EnvironmentError: |
223 except EnvironmentError: |
224 raise util.Abort(_("unable to read file list (%s)") % pat) |
224 raise util.Abort(_("unable to read file list (%s)") % pat) |
225 kindpats += self._normalize(files, default, root, cwd, auditor) |
225 for k, p, source in self._normalize(files, default, root, cwd, |
|
226 auditor): |
|
227 kindpats.append((k, p, pat)) |
226 continue |
228 continue |
227 # else: re or relre - which cannot be normalized |
229 # else: re or relre - which cannot be normalized |
228 kindpats.append((kind, pat)) |
230 kindpats.append((kind, pat, '')) |
229 return kindpats |
231 return kindpats |
230 |
232 |
231 def exact(root, cwd, files): |
233 def exact(root, cwd, files): |
232 return match(root, cwd, files, exact=True) |
234 return match(root, cwd, files, exact=True) |
233 |
235 |
313 |
315 |
314 def _normalize(self, patterns, default, root, cwd, auditor): |
316 def _normalize(self, patterns, default, root, cwd, auditor): |
315 self._kp = super(icasefsmatcher, self)._normalize(patterns, default, |
317 self._kp = super(icasefsmatcher, self)._normalize(patterns, default, |
316 root, cwd, auditor) |
318 root, cwd, auditor) |
317 kindpats = [] |
319 kindpats = [] |
318 for kind, pats in self._kp: |
320 for kind, pats, source in self._kp: |
319 if kind not in ('re', 'relre'): # regex can't be normalized |
321 if kind not in ('re', 'relre'): # regex can't be normalized |
320 pats = self._dsnormalize(pats) |
322 pats = self._dsnormalize(pats) |
321 kindpats.append((kind, pats)) |
323 kindpats.append((kind, pats, source)) |
322 return kindpats |
324 return kindpats |
323 |
325 |
324 def patkind(pattern, default=None): |
326 def patkind(pattern, default=None): |
325 '''If pattern is 'kind:pat' with a known kind, return kind.''' |
327 '''If pattern is 'kind:pat' with a known kind, return kind.''' |
326 return _patsplit(pattern, default)[0] |
328 return _patsplit(pattern, default)[0] |
447 def _buildregexmatch(kindpats, globsuffix): |
449 def _buildregexmatch(kindpats, globsuffix): |
448 """Build a match function from a list of kinds and kindpats, |
450 """Build a match function from a list of kinds and kindpats, |
449 return regexp string and a matcher function.""" |
451 return regexp string and a matcher function.""" |
450 try: |
452 try: |
451 regex = '(?:%s)' % '|'.join([_regex(k, p, globsuffix) |
453 regex = '(?:%s)' % '|'.join([_regex(k, p, globsuffix) |
452 for (k, p) in kindpats]) |
454 for (k, p, s) in kindpats]) |
453 if len(regex) > 20000: |
455 if len(regex) > 20000: |
454 raise OverflowError |
456 raise OverflowError |
455 return regex, _rematcher(regex) |
457 return regex, _rematcher(regex) |
456 except OverflowError: |
458 except OverflowError: |
457 # We're using a Python with a tiny regex engine and we |
459 # We're using a Python with a tiny regex engine and we |
462 raise |
464 raise |
463 regexa, a = _buildregexmatch(kindpats[:l//2], globsuffix) |
465 regexa, a = _buildregexmatch(kindpats[:l//2], globsuffix) |
464 regexb, b = _buildregexmatch(kindpats[l//2:], globsuffix) |
466 regexb, b = _buildregexmatch(kindpats[l//2:], globsuffix) |
465 return regex, lambda s: a(s) or b(s) |
467 return regex, lambda s: a(s) or b(s) |
466 except re.error: |
468 except re.error: |
467 for k, p in kindpats: |
469 for k, p, s in kindpats: |
468 try: |
470 try: |
469 _rematcher('(?:%s)' % _regex(k, p, globsuffix)) |
471 _rematcher('(?:%s)' % _regex(k, p, globsuffix)) |
470 except re.error: |
472 except re.error: |
471 raise util.Abort(_("invalid pattern (%s): %s") % (k, p)) |
473 if s: |
|
474 raise util.Abort(_("%s: invalid pattern (%s): %s") % |
|
475 (s, k, p)) |
|
476 else: |
|
477 raise util.Abort(_("invalid pattern (%s): %s") % (k, p)) |
472 raise util.Abort(_("invalid pattern")) |
478 raise util.Abort(_("invalid pattern")) |
473 |
479 |
474 def _roots(kindpats): |
480 def _roots(kindpats): |
475 '''return roots and exact explicitly listed files from patterns |
481 '''return roots and exact explicitly listed files from patterns |
476 |
482 |
477 >>> _roots([('glob', 'g/*'), ('glob', 'g'), ('glob', 'g*')]) |
483 >>> _roots([('glob', 'g/*', ''), ('glob', 'g', ''), ('glob', 'g*', '')]) |
478 ['g', 'g', '.'] |
484 ['g', 'g', '.'] |
479 >>> _roots([('relpath', 'r'), ('path', 'p/p'), ('path', '')]) |
485 >>> _roots([('relpath', 'r', ''), ('path', 'p/p', ''), ('path', '', '')]) |
480 ['r', 'p/p', '.'] |
486 ['r', 'p/p', '.'] |
481 >>> _roots([('relglob', 'rg*'), ('re', 're/'), ('relre', 'rr')]) |
487 >>> _roots([('relglob', 'rg*', ''), ('re', 're/', ''), ('relre', 'rr', '')]) |
482 ['.', '.', '.'] |
488 ['.', '.', '.'] |
483 ''' |
489 ''' |
484 r = [] |
490 r = [] |
485 for kind, pat in kindpats: |
491 for kind, pat, source in kindpats: |
486 if kind == 'glob': # find the non-glob prefix |
492 if kind == 'glob': # find the non-glob prefix |
487 root = [] |
493 root = [] |
488 for p in pat.split('/'): |
494 for p in pat.split('/'): |
489 if '[' in p or '{' in p or '*' in p or '?' in p: |
495 if '[' in p or '{' in p or '*' in p or '?' in p: |
490 break |
496 break |
495 else: # relglob, re, relre |
501 else: # relglob, re, relre |
496 r.append('.') |
502 r.append('.') |
497 return r |
503 return r |
498 |
504 |
499 def _anypats(kindpats): |
505 def _anypats(kindpats): |
500 for kind, pat in kindpats: |
506 for kind, pat, source in kindpats: |
501 if kind in ('glob', 're', 'relglob', 'relre', 'set'): |
507 if kind in ('glob', 're', 'relglob', 'relre', 'set'): |
502 return True |
508 return True |
503 |
509 |
504 _commentre = None |
510 _commentre = None |
505 |
511 |