mercurial/util.py
changeset 888 e7a943e8c52b
parent 886 509de8ab6f31
child 890 391de0bcc722
child 894 62ec665759f2
equal deleted inserted replaced
886:509de8ab6f31 888:e7a943e8c52b
    93     else:
    93     else:
    94         raise Abort('%s not under repository root' % myname)
    94         raise Abort('%s not under repository root' % myname)
    95     
    95     
    96 def matcher(repo, cwd, names, inc, exc, head = ''):
    96 def matcher(repo, cwd, names, inc, exc, head = ''):
    97     def patkind(name):
    97     def patkind(name):
    98         for prefix in 're:', 'glob:', 'path:':
    98         for prefix in 're:', 'glob:', 'path:', 'relpath:':
    99             if name.startswith(prefix): return name.split(':', 1)
    99             if name.startswith(prefix): return name.split(':', 1)
   100         for c in name:
   100         for c in name:
   101             if c in _globchars: return 'glob', name
   101             if c in _globchars: return 'glob', name
   102         return 'relpath', name
   102         return 'relpath', name
   103 
   103 
   104     def regex(name, tail):
   104     def regex(kind, name, tail):
   105         '''convert a pattern into a regular expression'''
   105         '''convert a pattern into a regular expression'''
   106         kind, name = patkind(name)
       
   107         if kind == 're':
   106         if kind == 're':
   108             return name
   107             return name
   109         elif kind == 'path':
   108         elif kind == 'path':
   110             return '^' + re.escape(name) + '$'
   109             return '^' + re.escape(name) + '(?:/|$)'
       
   110         elif kind == 'relpath':
       
   111             return head + re.escape(name) + tail
   111         return head + globre(name, '', tail)
   112         return head + globre(name, '', tail)
   112 
   113 
   113     def matchfn(pats, tail):
   114     def matchfn(pats, tail):
   114         """build a matching function from a set of patterns"""
   115         """build a matching function from a set of patterns"""
   115         if pats:
   116         if pats:
   116             pat = '(?:%s)' % '|'.join([regex(p, tail) for p in pats])
   117             pat = '(?:%s)' % '|'.join([regex(k, p, tail) for (k, p) in pats])
   117             return re.compile(pat).match
   118             return re.compile(pat).match
   118 
   119 
   119     def globprefix(pat):
   120     def globprefix(pat):
   120         '''return the non-glob prefix of a path, e.g. foo/* -> foo'''
   121         '''return the non-glob prefix of a path, e.g. foo/* -> foo'''
   121         root = []
   122         root = []
   130     for kind, name in map(patkind, names):
   131     for kind, name in map(patkind, names):
   131         if kind in ('glob', 'relpath'):
   132         if kind in ('glob', 'relpath'):
   132             name = canonpath(repo, cwd, name)
   133             name = canonpath(repo, cwd, name)
   133             if name == '':
   134             if name == '':
   134                 kind, name = 'glob', '**'
   135                 kind, name = 'glob', '**'
   135         if kind in ('glob', 're'):
   136         if kind in ('glob', 'path', 're'):
   136             pats.append(name)
   137             pats.append((kind, name))
   137         if kind == 'glob':
   138         if kind == 'glob':
   138             root = globprefix(name)
   139             root = globprefix(name)
   139             if root: roots.append(root)
   140             if root: roots.append(root)
   140         elif kind == 'relpath':
   141         elif kind == 'relpath':
   141             files.append(name)
   142             files.append((kind, name))
   142             roots.append(name)
   143             roots.append(name)
   143         
   144         
   144     patmatch = matchfn(pats, '$') or always
   145     patmatch = matchfn(pats, '$') or always
   145     filematch = matchfn(files, '(?:/|$)') or always
   146     filematch = matchfn(files, '(?:/|$)') or always
   146     incmatch = matchfn(inc, '(?:/|$)') or always
   147     incmatch = matchfn(map(patkind, inc), '(?:/|$)') or always
   147     excmatch = matchfn(exc, '(?:/|$)') or (lambda fn: False)
   148     excmatch = matchfn(map(patkind, exc), '(?:/|$)') or (lambda fn: False)
   148 
   149 
   149     return roots, lambda fn: (incmatch(fn) and not excmatch(fn) and
   150     return roots, lambda fn: (incmatch(fn) and not excmatch(fn) and
   150                               (fn.endswith('/') or
   151                               (fn.endswith('/') or
   151                                (not pats and not files) or
   152                                (not pats and not files) or
   152                                (pats and patmatch(fn)) or
   153                                (pats and patmatch(fn)) or