mercurial/match.py
changeset 32502 3026f19b4b01
parent 32501 7095dbc266e3
child 32503 361808a2b0b8
equal deleted inserted replaced
32501:7095dbc266e3 32502:3026f19b4b01
   147     else:
   147     else:
   148         m = patternmatcher(root, cwd, normalize, patterns, include=None,
   148         m = patternmatcher(root, cwd, normalize, patterns, include=None,
   149                            default=default, auditor=auditor, ctx=ctx,
   149                            default=default, auditor=auditor, ctx=ctx,
   150                            listsubrepos=listsubrepos, warn=warn, badfn=badfn)
   150                            listsubrepos=listsubrepos, warn=warn, badfn=badfn)
   151     if include:
   151     if include:
   152         im = includematcher(root, cwd, normalize, [], include=include,
   152         im = includematcher(root, cwd, normalize, include, auditor=auditor,
   153                             default=default, auditor=auditor, ctx=ctx,
   153                             ctx=ctx, listsubrepos=listsubrepos, warn=warn,
   154                             listsubrepos=listsubrepos, warn=warn, badfn=None)
   154                             badfn=None)
   155         m = intersectmatchers(m, im)
   155         m = intersectmatchers(m, im)
   156     if exclude:
   156     if exclude:
   157         em = includematcher(root, cwd, normalize, [], include=exclude,
   157         em = includematcher(root, cwd, normalize, exclude, auditor=auditor,
   158                             default=default, auditor=auditor, ctx=ctx,
   158                             ctx=ctx, listsubrepos=listsubrepos, warn=warn,
   159                             listsubrepos=listsubrepos, warn=warn, badfn=None)
   159                             badfn=None)
   160         m = differencematcher(m, em)
   160         m = differencematcher(m, em)
   161     return m
   161     return m
   162 
   162 
   163 def exact(root, cwd, files, badfn=None):
   163 def exact(root, cwd, files, badfn=None):
   164     return exactmatcher(root, cwd, files, badfn=badfn)
   164     return exactmatcher(root, cwd, files, badfn=badfn)
   401         return ('<patternmatcher patterns=%r, includes=%r>' %
   401         return ('<patternmatcher patterns=%r, includes=%r>' %
   402                 (self.patternspat, self.includepat))
   402                 (self.patternspat, self.includepat))
   403 
   403 
   404 class includematcher(basematcher):
   404 class includematcher(basematcher):
   405 
   405 
   406     def __init__(self, root, cwd, normalize, patterns, include=None,
   406     def __init__(self, root, cwd, normalize, include, auditor=None, ctx=None,
   407                  default='glob', auditor=None, ctx=None,
       
   408                  listsubrepos=False, warn=None, badfn=None):
   407                  listsubrepos=False, warn=None, badfn=None):
   409         super(includematcher, self).__init__(root, cwd, badfn,
   408         super(includematcher, self).__init__(root, cwd, badfn)
   410                                              relativeuipath=bool(include or
   409 
   411                                                                  patterns))
   410         kindpats = normalize(include, 'glob', root, cwd, auditor, warn)
   412         if include is None:
   411         self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)',
   413             include = []
   412                                           listsubrepos, root)
   414 
   413         self._anyincludepats = _anypats(kindpats)
   415         self._anypats = bool(include)
   414         roots, dirs = _rootsanddirs(kindpats)
   416         self._anyincludepats = False
       
   417         self._always = False
       
   418         self.patternspat = None
       
   419         self.includepat = None
       
   420 
       
   421         # roots are directories which are recursively included.
   415         # roots are directories which are recursively included.
   422         self._includeroots = set()
   416         self._includeroots = set(roots)
   423         # dirs are directories which are non-recursively included.
   417         # dirs are directories which are non-recursively included.
   424         self._includedirs = set()
   418         self._includedirs = set(dirs)
   425 
   419         self.matchfn = im
   426         matchfns = []
       
   427         if include:
       
   428             kindpats = normalize(include, 'glob', root, cwd, auditor, warn)
       
   429             self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)',
       
   430                                               listsubrepos, root)
       
   431             self._anyincludepats = _anypats(kindpats)
       
   432             roots, dirs = _rootsanddirs(kindpats)
       
   433             self._includeroots.update(roots)
       
   434             self._includedirs.update(dirs)
       
   435             matchfns.append(im)
       
   436         if patterns:
       
   437             kindpats = normalize(patterns, default, root, cwd, auditor, warn)
       
   438             if not _kindpatsalwaysmatch(kindpats):
       
   439                 self._files = _explicitfiles(kindpats)
       
   440                 self._anypats = self._anypats or _anypats(kindpats)
       
   441                 self.patternspat, pm = _buildmatch(ctx, kindpats, '$',
       
   442                                                    listsubrepos, root)
       
   443                 matchfns.append(pm)
       
   444 
       
   445         if not matchfns:
       
   446             m = util.always
       
   447             self._always = True
       
   448         elif len(matchfns) == 1:
       
   449             m = matchfns[0]
       
   450         else:
       
   451             def m(f):
       
   452                 for matchfn in matchfns:
       
   453                     if not matchfn(f):
       
   454                         return False
       
   455                 return True
       
   456 
       
   457         self.matchfn = m
       
   458 
       
   459     @propertycache
       
   460     def _dirs(self):
       
   461         return set(util.dirs(self._fileset)) | {'.'}
       
   462 
   420 
   463     def visitdir(self, dir):
   421     def visitdir(self, dir):
   464         if self.prefix() and dir in self._fileset:
   422         if not self._anyincludepats and dir in self._includeroots:
       
   423             # The condition above is essentially self.prefix() for includes
   465             return 'all'
   424             return 'all'
   466         if self._includeroots or self._includedirs:
   425         if ('.' not in self._includeroots and
   467             if (not self._anyincludepats and
   426             dir not in self._includeroots and
   468                 dir in self._includeroots):
   427             dir not in self._includedirs and
   469                 # The condition above is essentially self.prefix() for includes
   428             not any(parent in self._includeroots
   470                 return 'all'
   429                     for parent in util.finddirs(dir))):
   471             if ('.' not in self._includeroots and
   430             return False
   472                 dir not in self._includeroots and
   431         return True
   473                 dir not in self._includedirs and
       
   474                 not any(parent in self._includeroots
       
   475                         for parent in util.finddirs(dir))):
       
   476                 return False
       
   477         return (not self._fileset or
       
   478                 '.' in self._fileset or
       
   479                 dir in self._fileset or
       
   480                 dir in self._dirs or
       
   481                 any(parentdir in self._fileset
       
   482                     for parentdir in util.finddirs(dir)))
       
   483 
   432 
   484     def anypats(self):
   433     def anypats(self):
   485         return self._anypats
   434         return True
   486 
       
   487     def always(self):
       
   488         return self._always
       
   489 
   435 
   490     def __repr__(self):
   436     def __repr__(self):
   491         return ('<includematcher patterns=%r, includes=%r>' %
   437         return ('<includematcher includes=%r>' % self.includepat)
   492                 (self.patternspat, self.includepat))
       
   493 
   438 
   494 class exactmatcher(basematcher):
   439 class exactmatcher(basematcher):
   495     '''Matches the input files exactly. They are interpreted as paths, not
   440     '''Matches the input files exactly. They are interpreted as paths, not
   496     patterns (so no kind-prefixes).
   441     patterns (so no kind-prefixes).
   497     '''
   442     '''