mercurial/dirstate.py
changeset 6829 fec1da46006e
parent 6828 55d65a33da52
child 6830 2cf4cda64727
equal deleted inserted replaced
6828:55d65a33da52 6829:fec1da46006e
   469         supported = self._supported
   469         supported = self._supported
   470         _join = self._join
   470         _join = self._join
   471         work = []
   471         work = []
   472         wadd = work.append
   472         wadd = work.append
   473 
   473 
   474         seen = {'.hg': 1}
   474         results = {}
   475 
   475 
   476         # step 1: find all explicit files
   476         # step 1: find all explicit files
   477         for ff in util.sort(files):
   477         for ff in util.sort(files):
   478             nf = normalize(normpath(ff))
   478             nf = normalize(normpath(ff))
   479             if nf in seen:
   479             if nf in results:
   480                 continue
   480                 continue
   481 
   481 
   482             try:
   482             try:
   483                 st = lstat(_join(nf))
   483                 st = lstat(_join(nf))
   484                 if isdir(st.st_mode):
   484                 if isdir(st.st_mode):
   485                     if not dirignore(nf):
   485                     if not dirignore(nf):
   486                         wadd(nf)
   486                         wadd(nf)
   487                 else:
   487                 else:
   488                     seen[nf] = 1
       
   489                     if supported(ff, st.st_mode, verbose=True):
   488                     if supported(ff, st.st_mode, verbose=True):
   490                         yield nf, st
   489                         results[nf] = st
   491                     elif nf in dmap:
   490                     elif nf in dmap:
   492                         yield nf, None
   491                         results[nf] = None
   493             except OSError, inst:
   492             except OSError, inst:
   494                 keep = False
   493                 keep = False
   495                 prefix = nf + "/"
   494                 prefix = nf + "/"
   496                 for fn in dmap:
   495                 for fn in dmap:
   497                     if nf == fn or fn.startswith(prefix):
   496                     if nf == fn or fn.startswith(prefix):
   499                         break
   498                         break
   500                 if not keep:
   499                 if not keep:
   501                     if inst.errno != errno.ENOENT:
   500                     if inst.errno != errno.ENOENT:
   502                         fwarn(ff, inst.strerror)
   501                         fwarn(ff, inst.strerror)
   503                     elif badfn(ff, inst.strerror) and imatch(nf):
   502                     elif badfn(ff, inst.strerror) and imatch(nf):
   504                         yield nf, None
   503                         results[nf] = None
   505 
   504 
   506         # step 2: visit subdirectories
   505         # step 2: visit subdirectories
   507         while work:
   506         while work:
   508             nd = work.pop()
   507             nd = work.pop()
   509             if hasattr(match, 'dir'):
   508             if hasattr(match, 'dir'):
   510                 match.dir(nd)
   509                 match.dir(nd)
   511             entries = listdir(_join(nd), stat=True)
   510             entries = listdir(_join(nd), stat=True)
   512             if nd == '.':
   511             if nd == '.':
   513                 nd = ''
   512                 nd = ''
       
   513             elif nd == '.hg':
       
   514                 continue
   514             else:
   515             else:
   515                 # do not recurse into a repo contained in this
   516                 # do not recurse into a repo contained in this
   516                 # one. use bisect to find .hg directory so speed
   517                 # one. use bisect to find .hg directory so speed
   517                 # is good on big directory.
   518                 # is good on big directory.
   518                 hg = bisect_left(entries, ('.hg'))
   519                 hg = bisect_left(entries, ('.hg'))
   519                 if hg < len(entries) and entries[hg][0] == '.hg' \
   520                 if hg < len(entries) and entries[hg][0] == '.hg' \
   520                         and entries[hg][1] == dirkind:
   521                         and entries[hg][1] == dirkind:
   521                         continue
   522                         continue
   522             for f, kind, st in entries:
   523             for f, kind, st in entries:
   523                 nf = normalize(nd and (nd + "/" + f) or f)
   524                 nf = normalize(nd and (nd + "/" + f) or f)
   524                 if nf not in seen:
   525                 if nf not in results:
   525                     seen[nf] = 1
       
   526                     if kind == dirkind:
   526                     if kind == dirkind:
   527                         if not ignore(nf):
   527                         if not ignore(nf):
   528                             wadd(nf)
   528                             wadd(nf)
   529                         if nf in dmap and match(nf):
   529                         if nf in dmap and match(nf):
   530                             yield nf, None
   530                             results[nf] = None
   531                     elif imatch(nf):
   531                     elif imatch(nf):
   532                         if supported(nf, st.st_mode):
   532                         if supported(nf, st.st_mode):
   533                             yield nf, st
   533                             results[nf] = st
   534                         elif nf in dmap:
   534                         elif nf in dmap:
   535                             yield nf, None
   535                             results[nf] = None
   536 
   536 
   537         # step 3: report unseen items in the dmap hash
   537         # step 3: report unseen items in the dmap hash
   538         for f in util.sort(dmap):
   538         for f in util.sort(dmap):
   539             if f not in seen and match(f):
   539             if f not in results and match(f):
       
   540                 results[f] = None
   540                 try:
   541                 try:
   541                     st = lstat(_join(f))
   542                     st = lstat(_join(f))
   542                     if supported(f, st.st_mode):
   543                     if supported(f, st.st_mode):
   543                         yield f, st
   544                         results[f] = st
   544                         continue
       
   545                 except OSError, inst:
   545                 except OSError, inst:
   546                     if inst.errno not in (errno.ENOENT, errno.ENOTDIR):
   546                     if inst.errno not in (errno.ENOENT, errno.ENOTDIR):
   547                         raise
   547                         raise
   548                 yield f, None
   548 
       
   549         return results
   549 
   550 
   550     def status(self, match, ignored, clean, unknown):
   551     def status(self, match, ignored, clean, unknown):
   551         listignored, listclean, listunknown = ignored, clean, unknown
   552         listignored, listclean, listunknown = ignored, clean, unknown
   552         lookup, modified, added, unknown, ignored = [], [], [], [], []
   553         lookup, modified, added, unknown, ignored = [], [], [], [], []
   553         removed, deleted, clean = [], [], []
   554         removed, deleted, clean = [], [], []
   563         iadd = ignored.append
   564         iadd = ignored.append
   564         radd = removed.append
   565         radd = removed.append
   565         dadd = deleted.append
   566         dadd = deleted.append
   566         cadd = clean.append
   567         cadd = clean.append
   567 
   568 
   568         for fn, st in self.walk(match, listunknown, listignored):
   569         for fn, st in self.walk(match, listunknown, listignored).iteritems():
   569             if fn not in dmap:
   570             if fn not in dmap:
   570                 if (listignored or match.exact(fn)) and self._dirignore(fn):
   571                 if (listignored or match.exact(fn)) and self._dirignore(fn):
   571                     if listignored:
   572                     if listignored:
   572                         iadd(fn)
   573                         iadd(fn)
   573                 elif listunknown:
   574                 elif listunknown: