mercurial/dirstate.py
changeset 5001 46facb73ba8b
parent 4965 4106dde15aed
child 5002 62e3fd2baca4
equal deleted inserted replaced
5000:54ff1bb4b53a 5001:46facb73ba8b
   361 
   361 
   362         # self._root may end with a path separator when self._root == '/'
   362         # self._root may end with a path separator when self._root == '/'
   363         common_prefix_len = len(self._root)
   363         common_prefix_len = len(self._root)
   364         if not self._root.endswith(os.sep):
   364         if not self._root.endswith(os.sep):
   365             common_prefix_len += 1
   365             common_prefix_len += 1
       
   366 
   366         # recursion free walker, faster than os.walk.
   367         # recursion free walker, faster than os.walk.
       
   368         normpath = util.normpath
       
   369         listdir = os.listdir
       
   370         lstat = os.lstat
       
   371         bisect_left = bisect.bisect_left
       
   372         isdir = os.path.isdir
       
   373         pconvert = util.pconvert
       
   374         join = os.path.join
       
   375         s_isdir = stat.S_ISDIR
       
   376         supported = self._supported
       
   377 
   367         def findfiles(s):
   378         def findfiles(s):
   368             work = [s]
   379             work = [s]
   369             if directories:
   380             if directories:
   370                 yield 'd', util.normpath(s[common_prefix_len:]), os.lstat(s)
   381                 yield 'd', normpath(s[common_prefix_len:]), os.lstat(s)
   371             while work:
   382             while work:
   372                 top = work.pop()
   383                 top = work.pop()
   373                 names = os.listdir(top)
   384                 names = listdir(top)
   374                 names.sort()
   385                 names.sort()
   375                 # nd is the top of the repository dir tree
   386                 # nd is the top of the repository dir tree
   376                 nd = util.normpath(top[common_prefix_len:])
   387                 nd = normpath(top[common_prefix_len:])
   377                 if nd == '.':
   388                 if nd == '.':
   378                     nd = ''
   389                     nd = ''
   379                 else:
   390                 else:
   380                     # do not recurse into a repo contained in this
   391                     # do not recurse into a repo contained in this
   381                     # one. use bisect to find .hg directory so speed
   392                     # one. use bisect to find .hg directory so speed
   382                     # is good on big directory.
   393                     # is good on big directory.
   383                     hg = bisect.bisect_left(names, '.hg')
   394                     hg = bisect_left(names, '.hg')
   384                     if hg < len(names) and names[hg] == '.hg':
   395                     if hg < len(names) and names[hg] == '.hg':
   385                         if os.path.isdir(os.path.join(top, '.hg')):
   396                         if isdir(join(top, '.hg')):
   386                             continue
   397                             continue
   387                 for f in names:
   398                 for f in names:
   388                     np = util.pconvert(os.path.join(nd, f))
   399                     np = pconvert(os.path.join(nd, f))
   389                     if seen(np):
   400                     if seen(np):
   390                         continue
   401                         continue
   391                     p = os.path.join(top, f)
   402                     p = join(top, f)
   392                     # don't trip over symlinks
   403                     # don't trip over symlinks
   393                     st = os.lstat(p)
   404                     st = lstat(p)
   394                     if stat.S_ISDIR(st.st_mode):
   405                     if s_isdir(st.st_mode):
   395                         if not ignore(np):
   406                         if not ignore(np):
   396                             work.append(p)
   407                             work.append(p)
   397                             if directories:
   408                             if directories:
   398                                 yield 'd', np, st
   409                                 yield 'd', np, st
   399                         if imatch(np) and np in dc:
   410                         if imatch(np) and np in dc:
   400                             yield 'm', np, st
   411                             yield 'm', np, st
   401                     elif imatch(np):
   412                     elif imatch(np):
   402                         if self._supported(np, st):
   413                         if supported(np, st):
   403                             yield 'f', np, st
   414                             yield 'f', np, st
   404                         elif np in dc:
   415                         elif np in dc:
   405                             yield 'm', np, st
   416                             yield 'm', np, st
   406 
   417 
   407         known = {'.hg': 1}
   418         known = {'.hg': 1}
   410             known[fn] = 1
   421             known[fn] = 1
   411 
   422 
   412         # step one, find all files that match our criteria
   423         # step one, find all files that match our criteria
   413         files.sort()
   424         files.sort()
   414         for ff in files:
   425         for ff in files:
   415             nf = util.normpath(ff)
   426             nf = normpath(ff)
   416             f = self._join(ff)
   427             f = self._join(ff)
   417             try:
   428             try:
   418                 st = os.lstat(f)
   429                 st = lstat(f)
   419             except OSError, inst:
   430             except OSError, inst:
   420                 found = False
   431                 found = False
   421                 for fn in dc:
   432                 for fn in dc:
   422                     if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'):
   433                     if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'):
   423                         found = True
   434                         found = True
   427                         self._ui.warn('%s: %s\n' %
   438                         self._ui.warn('%s: %s\n' %
   428                                       (self.pathto(ff), inst.strerror))
   439                                       (self.pathto(ff), inst.strerror))
   429                     elif badmatch and badmatch(ff) and imatch(nf):
   440                     elif badmatch and badmatch(ff) and imatch(nf):
   430                         yield 'b', ff, None
   441                         yield 'b', ff, None
   431                 continue
   442                 continue
   432             if stat.S_ISDIR(st.st_mode):
   443             if s_isdir(st.st_mode):
   433                 cmp1 = (lambda x, y: cmp(x[1], y[1]))
   444                 cmp1 = (lambda x, y: cmp(x[1], y[1]))
   434                 sorted_ = [ x for x in findfiles(f) ]
   445                 sorted_ = [ x for x in findfiles(f) ]
   435                 sorted_.sort(cmp1)
   446                 sorted_.sort(cmp1)
   436                 for e in sorted_:
   447                 for e in sorted_:
   437                     yield e
   448                     yield e
   438             else:
   449             else:
   439                 if not seen(nf) and match(nf):
   450                 if not seen(nf) and match(nf):
   440                     if self._supported(ff, st, verbose=True):
   451                     if supported(ff, st, verbose=True):
   441                         yield 'f', nf, st
   452                         yield 'f', nf, st
   442                     elif ff in dc:
   453                     elif ff in dc:
   443                         yield 'm', nf, st
   454                         yield 'm', nf, st
   444 
   455 
   445         # step two run through anything left in the dc hash and yield
   456         # step two run through anything left in the dc hash and yield