mercurial/dirstate.py
changeset 6831 2b663f542bd3
parent 6830 2cf4cda64727
child 6832 643ff33812f8
equal deleted inserted replaced
6830:2cf4cda64727 6831:2b663f542bd3
   422             return False
   422             return False
   423         badfn = fwarn
   423         badfn = fwarn
   424         if hasattr(match, 'bad'):
   424         if hasattr(match, 'bad'):
   425             badfn = match.bad
   425             badfn = match.bad
   426 
   426 
   427         files = util.unique(match.files())
       
   428         if not files or '.' in files:
       
   429             files = ['']
       
   430         dmap = self._map
       
   431 
       
   432         def imatch(file_):
       
   433             if file_ not in dmap and self._ignore(file_):
       
   434                 return False
       
   435             return match(file_)
       
   436 
       
   437         def badtype(f, mode):
   427         def badtype(f, mode):
   438             kind = 'unknown'
   428             kind = 'unknown'
   439             if stat.S_ISCHR(mode): kind = _('character device')
   429             if stat.S_ISCHR(mode): kind = _('character device')
   440             elif stat.S_ISBLK(mode): kind = _('block device')
   430             elif stat.S_ISBLK(mode): kind = _('block device')
   441             elif stat.S_ISFIFO(mode): kind = _('fifo')
   431             elif stat.S_ISFIFO(mode): kind = _('fifo')
   442             elif stat.S_ISSOCK(mode): kind = _('socket')
   432             elif stat.S_ISSOCK(mode): kind = _('socket')
   443             elif stat.S_ISDIR(mode): kind = _('directory')
   433             elif stat.S_ISDIR(mode): kind = _('directory')
   444             self._ui.warn(_('%s: unsupported file type (type is %s)\n')
   434             self._ui.warn(_('%s: unsupported file type (type is %s)\n')
   445                           % (self.pathto(f), kind))
   435                           % (self.pathto(f), kind))
   446 
   436 
       
   437         def imatch(f):
       
   438             return (f in dmap or not ignore(f)) and match(f)
       
   439 
   447         # TODO: don't walk unknown directories if unknown and ignored are False
   440         # TODO: don't walk unknown directories if unknown and ignored are False
   448         ignore = self._ignore
   441         ignore = self._ignore
   449         dirignore = self._dirignore
   442         dirignore = self._dirignore
   450         if ignored:
   443         if ignored:
   451             imatch = match
   444             imatch = match
   452             ignore = util.never
   445             ignore = util.never
   453             dirignore = util.never
   446             dirignore = util.never
   454 
   447 
       
   448         dmap = self._map
   455         normpath = util.normpath
   449         normpath = util.normpath
   456         normalize = self.normalize
   450         normalize = self.normalize
   457         listdir = osutil.listdir
   451         listdir = osutil.listdir
   458         lstat = os.lstat
   452         lstat = os.lstat
   459         bisect_left = bisect.bisect_left
   453         bisect_left = bisect.bisect_left
   460         pconvert = util.pconvert
   454         pconvert = util.pconvert
   461         join = os.path.join
       
   462         getkind = stat.S_IFMT
   455         getkind = stat.S_IFMT
   463         dirkind = stat.S_IFDIR
   456         dirkind = stat.S_IFDIR
   464         regkind = stat.S_IFREG
   457         regkind = stat.S_IFREG
   465         lnkkind = stat.S_IFLNK
   458         lnkkind = stat.S_IFLNK
   466         _join = self._join
   459         join = self._join
   467         work = []
   460         work = []
   468         wadd = work.append
   461         wadd = work.append
   469 
   462 
   470         results = {}
   463         files = util.unique(match.files())
       
   464         if not files or '.' in files:
       
   465             files = ['']
       
   466         results = {'.hg': None}
   471 
   467 
   472         # step 1: find all explicit files
   468         # step 1: find all explicit files
   473         for ff in util.sort(files):
   469         for ff in util.sort(files):
   474             nf = normalize(normpath(ff))
   470             nf = normalize(normpath(ff))
   475             if nf in results:
   471             if nf in results:
   476                 continue
   472                 continue
   477 
   473 
   478             try:
   474             try:
   479                 st = lstat(_join(nf))
   475                 st = lstat(join(nf))
   480                 kind = getkind(st.st_mode)
   476                 kind = getkind(st.st_mode)
   481                 if kind == dirkind:
   477                 if kind == dirkind:
   482                     if not dirignore(nf):
   478                     if not dirignore(nf):
   483                         wadd(nf)
   479                         wadd(nf)
   484                 elif kind == regkind or kind == lnkkind:
   480                 elif kind == regkind or kind == lnkkind:
   503         # step 2: visit subdirectories
   499         # step 2: visit subdirectories
   504         while work:
   500         while work:
   505             nd = work.pop()
   501             nd = work.pop()
   506             if hasattr(match, 'dir'):
   502             if hasattr(match, 'dir'):
   507                 match.dir(nd)
   503                 match.dir(nd)
   508             entries = listdir(_join(nd), stat=True)
   504             entries = listdir(join(nd), stat=True)
   509             if nd == '.':
   505             if nd == '.':
   510                 nd = ''
   506                 nd = ''
   511             elif nd == '.hg':
       
   512                 continue
       
   513             else:
   507             else:
   514                 # do not recurse into a repo contained in this
   508                 # do not recurse into a repo contained in this
   515                 # one. use bisect to find .hg directory so speed
   509                 # one. use bisect to find .hg directory so speed
   516                 # is good on big directory.
   510                 # is good on big directory.
   517                 hg = bisect_left(entries, ('.hg'))
   511                 hg = bisect_left(entries, ('.hg'))
   531                             results[nf] = st
   525                             results[nf] = st
   532                         elif nf in dmap:
   526                         elif nf in dmap:
   533                             results[nf] = None
   527                             results[nf] = None
   534 
   528 
   535         # step 3: report unseen items in the dmap hash
   529         # step 3: report unseen items in the dmap hash
   536         for f in util.sort(dmap):
   530         for nf in util.sort(dmap):
   537             if f not in results and match(f):
   531             if nf not in results and match(nf):
   538                 results[f] = None
   532                 results[nf] = None
   539                 try:
   533                 try:
   540                     st = lstat(_join(f))
   534                     st = lstat(join(nf))
   541                     kind = getkind(st.st_mode)
   535                     kind = getkind(st.st_mode)
   542                     if kind == regkind or kind == lnkkind:
   536                     if kind == regkind or kind == lnkkind:
   543                         results[f] = st
   537                         results[nf] = st
   544                 except OSError, inst:
   538                 except OSError, inst:
   545                     if inst.errno not in (errno.ENOENT, errno.ENOTDIR):
   539                     if inst.errno not in (errno.ENOENT, errno.ENOTDIR):
   546                         raise
   540                         raise
   547 
   541 
       
   542         del results['.hg']
   548         return results
   543         return results
   549 
   544 
   550     def status(self, match, ignored, clean, unknown):
   545     def status(self, match, ignored, clean, unknown):
   551         listignored, listclean, listunknown = ignored, clean, unknown
   546         listignored, listclean, listunknown = ignored, clean, unknown
   552         lookup, modified, added, unknown, ignored = [], [], [], [], []
   547         lookup, modified, added, unknown, ignored = [], [], [], [], []