445 def contains_glob(name): |
445 def contains_glob(name): |
446 for c in name: |
446 for c in name: |
447 if c in _globchars: return True |
447 if c in _globchars: return True |
448 return False |
448 return False |
449 |
449 |
450 def regex(kind, name): |
450 def regex(kind, name, tail): |
451 '''convert a pattern into a regular expression''' |
451 '''convert a pattern into a regular expression''' |
452 if not name: |
452 if not name: |
453 return '' |
453 return '' |
454 if kind == 're': |
454 if kind == 're': |
455 return name |
455 return name |
456 elif kind == 'path': |
456 elif kind == 'path': |
457 return '^' + re.escape(name) + '(?:/|$)' |
457 return '^' + re.escape(name) + '(?:/|$)' |
458 elif kind == 'relglob': |
458 elif kind == 'relglob': |
459 return globre(name, '(?:|.*/)', '(?:/|$)') |
459 return globre(name, '(?:|.*/)', tail) |
460 elif kind == 'relpath': |
460 elif kind == 'relpath': |
461 return re.escape(name) + '(?:/|$)' |
461 return re.escape(name) + '(?:/|$)' |
462 elif kind == 'relre': |
462 elif kind == 'relre': |
463 if name.startswith('^'): |
463 if name.startswith('^'): |
464 return name |
464 return name |
465 return '.*' + name |
465 return '.*' + name |
466 return globre(name, '', '(?:/|$)') |
466 return globre(name, '', tail) |
467 |
467 |
468 def matchfn(pats): |
468 def matchfn(pats, tail): |
469 """build a matching function from a set of patterns""" |
469 """build a matching function from a set of patterns""" |
470 if not pats: |
470 if not pats: |
471 return |
471 return |
472 matches = [] |
472 matches = [] |
473 for k, p in pats: |
473 for k, p in pats: |
474 try: |
474 try: |
475 pat = '(?:%s)' % regex(k, p) |
475 pat = '(?:%s)' % regex(k, p, tail) |
476 matches.append(re.compile(pat).match) |
476 matches.append(re.compile(pat).match) |
477 except re.error: |
477 except re.error: |
478 if src: raise Abort("%s: invalid pattern (%s): %s" % (src, k, p)) |
478 if src: raise Abort("%s: invalid pattern (%s): %s" % (src, k, p)) |
479 else: raise Abort("invalid pattern (%s): %s" % (k, p)) |
479 else: raise Abort("invalid pattern (%s): %s" % (k, p)) |
480 |
480 |
518 roots.append('.') |
518 roots.append('.') |
519 return roots, pats, anypats |
519 return roots, pats, anypats |
520 |
520 |
521 roots, pats, anypats = normalizepats(names, dflt_pat) |
521 roots, pats, anypats = normalizepats(names, dflt_pat) |
522 |
522 |
523 patmatch = matchfn(pats) or always |
523 patmatch = matchfn(pats, '$') or always |
524 incmatch = always |
524 incmatch = always |
525 if inc: |
525 if inc: |
526 dummy, inckinds, dummy = normalizepats(inc, 'glob') |
526 dummy, inckinds, dummy = normalizepats(inc, 'glob') |
527 incmatch = matchfn(inckinds) |
527 incmatch = matchfn(inckinds, '(?:/|$)') |
528 excmatch = lambda fn: False |
528 excmatch = lambda fn: False |
529 if exc: |
529 if exc: |
530 dummy, exckinds, dummy = normalizepats(exc, 'glob') |
530 dummy, exckinds, dummy = normalizepats(exc, 'glob') |
531 excmatch = matchfn(exckinds) |
531 excmatch = matchfn(exckinds, '(?:/|$)') |
532 |
532 |
533 if not names and inc and not exc: |
533 if not names and inc and not exc: |
534 # common case: hgignore patterns |
534 # common case: hgignore patterns |
535 match = incmatch |
535 match = incmatch |
536 else: |
536 else: |