mercurial/dirstate.py
changeset 6828 55d65a33da52
parent 6827 c978d6752dbb
child 6829 fec1da46006e
equal deleted inserted replaced
6827:c978d6752dbb 6828:55d65a33da52
   462         lstat = os.lstat
   462         lstat = os.lstat
   463         bisect_left = bisect.bisect_left
   463         bisect_left = bisect.bisect_left
   464         isdir = os.path.isdir
   464         isdir = os.path.isdir
   465         pconvert = util.pconvert
   465         pconvert = util.pconvert
   466         join = os.path.join
   466         join = os.path.join
   467         s_isdir = stat.S_ISDIR
   467         isdir = stat.S_ISDIR
       
   468         dirkind = stat.S_IFDIR
   468         supported = self._supported
   469         supported = self._supported
   469         _join = self._join
   470         _join = self._join
   470         work = []
   471         work = []
   471         wadd = work.append
   472         wadd = work.append
   472 
   473 
   478             if nf in seen:
   479             if nf in seen:
   479                 continue
   480                 continue
   480 
   481 
   481             try:
   482             try:
   482                 st = lstat(_join(nf))
   483                 st = lstat(_join(nf))
       
   484                 if isdir(st.st_mode):
       
   485                     if not dirignore(nf):
       
   486                         wadd(nf)
       
   487                 else:
       
   488                     seen[nf] = 1
       
   489                     if supported(ff, st.st_mode, verbose=True):
       
   490                         yield nf, st
       
   491                     elif nf in dmap:
       
   492                         yield nf, None
   483             except OSError, inst:
   493             except OSError, inst:
   484                 keep = False
   494                 keep = False
       
   495                 prefix = nf + "/"
   485                 for fn in dmap:
   496                 for fn in dmap:
   486                     if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'):
   497                     if nf == fn or fn.startswith(prefix):
   487                         keep = True
   498                         keep = True
   488                         break
   499                         break
   489                 if not keep:
   500                 if not keep:
   490                     if inst.errno != errno.ENOENT:
   501                     if inst.errno != errno.ENOENT:
   491                         fwarn(ff, inst.strerror)
   502                         fwarn(ff, inst.strerror)
   492                     elif badfn(ff, inst.strerror) and imatch(nf):
   503                     elif badfn(ff, inst.strerror) and imatch(nf):
   493                         yield nf, None
   504                         yield nf, None
   494                 continue
       
   495 
       
   496             if s_isdir(st.st_mode):
       
   497                 if not dirignore(nf):
       
   498                     wadd(nf)
       
   499             else:
       
   500                 seen[nf] = 1
       
   501                 if supported(ff, st.st_mode, verbose=True):
       
   502                     yield nf, st
       
   503                 elif nf in dmap:
       
   504                     yield nf, None
       
   505 
   505 
   506         # step 2: visit subdirectories
   506         # step 2: visit subdirectories
   507         while work:
   507         while work:
   508             nd = work.pop()
   508             nd = work.pop()
   509             if hasattr(match, 'dir'):
   509             if hasattr(match, 'dir'):
   510                 match.dir(nd)
   510                 match.dir(nd)
   511             entries = listdir(_join(nd), stat=True)
   511             entries = listdir(_join(nd), stat=True)
   512             # nd is the top of the repository dir tree
       
   513             if nd == '.':
   512             if nd == '.':
   514                 nd = ''
   513                 nd = ''
   515             else:
   514             else:
   516                 # do not recurse into a repo contained in this
   515                 # do not recurse into a repo contained in this
   517                 # one. use bisect to find .hg directory so speed
   516                 # one. use bisect to find .hg directory so speed
   518                 # is good on big directory.
   517                 # is good on big directory.
   519                 hg = bisect_left(entries, ('.hg'))
   518                 hg = bisect_left(entries, ('.hg'))
   520                 if hg < len(entries) and entries[hg][0] == '.hg' \
   519                 if hg < len(entries) and entries[hg][0] == '.hg' \
   521                         and entries[hg][1] == stat.S_IFDIR:
   520                         and entries[hg][1] == dirkind:
   522                         continue
   521                         continue
   523             for f, kind, st in entries:
   522             for f, kind, st in entries:
   524                 nf = normalize(pconvert(join(nd, f)))
   523                 nf = normalize(nd and (nd + "/" + f) or f)
   525                 if nf in seen:
   524                 if nf not in seen:
   526                     continue
   525                     seen[nf] = 1
   527                 seen[nf] = 1
   526                     if kind == dirkind:
   528                 # don't trip over symlinks
   527                         if not ignore(nf):
   529                 if kind == stat.S_IFDIR:
   528                             wadd(nf)
   530                     if not ignore(nf):
   529                         if nf in dmap and match(nf):
   531                         wadd(nf)
   530                             yield nf, None
   532                     if nf in dmap and match(nf):
   531                     elif imatch(nf):
   533                         yield nf, None
   532                         if supported(nf, st.st_mode):
   534                 elif imatch(nf):
   533                             yield nf, st
   535                     if supported(nf, st.st_mode):
   534                         elif nf in dmap:
   536                         yield nf, st
   535                             yield nf, None
   537                     elif nf in dmap:
       
   538                         yield nf, None
       
   539 
   536 
   540         # step 3: report unseen items in the dmap hash
   537         # step 3: report unseen items in the dmap hash
   541         for f in util.sort(dmap):
   538         for f in util.sort(dmap):
   542             if f in seen or not match(f):
   539             if f not in seen and match(f):
   543                 continue
   540                 try:
   544             seen[f] = 1
   541                     st = lstat(_join(f))
   545             try:
   542                     if supported(f, st.st_mode):
   546                 st = lstat(_join(f))
   543                         yield f, st
   547                 if supported(f, st.st_mode):
   544                         continue
   548                     yield f, st
   545                 except OSError, inst:
   549                     continue
   546                     if inst.errno not in (errno.ENOENT, errno.ENOTDIR):
   550             except OSError, inst:
   547                         raise
   551                 if inst.errno not in (errno.ENOENT, errno.ENOTDIR):
   548                 yield f, None
   552                     raise
       
   553             yield f, None
       
   554 
   549 
   555     def status(self, match, ignored, clean, unknown):
   550     def status(self, match, ignored, clean, unknown):
   556         listignored, listclean, listunknown = ignored, clean, unknown
   551         listignored, listclean, listunknown = ignored, clean, unknown
   557         lookup, modified, added, unknown, ignored = [], [], [], [], []
   552         lookup, modified, added, unknown, ignored = [], [], [], [], []
   558         removed, deleted, clean = [], [], []
   553         removed, deleted, clean = [], [], []