mercurial/dirstate.py
changeset 1487 2bc6cd62a29c
parent 1476 17e8c70fb670
child 1488 08c7851969cc
equal deleted inserted replaced
1486:d7809d6e9db2 1487:2bc6cd62a29c
   239                 else:
   239                 else:
   240                     break
   240                     break
   241                 bs += 1
   241                 bs += 1
   242         return ret
   242         return ret
   243 
   243 
       
   244     def supported_type(self, f, st, verbose=True):
       
   245         if stat.S_ISREG(st.st_mode):
       
   246             return True
       
   247         if verbose:
       
   248             kind = 'unknown'
       
   249             if stat.S_ISCHR(st.st_mode): kind = _('character device')
       
   250             elif stat.S_ISBLK(st.st_mode): kind = _('block device')
       
   251             elif stat.S_ISFIFO(st.st_mode): kind = _('fifo')
       
   252             elif stat.S_ISLNK(st.st_mode): kind = _('symbolic link')
       
   253             elif stat.S_ISSOCK(st.st_mode): kind = _('socket')
       
   254             elif stat.S_ISDIR(st.st_mode): kind = _('directory')
       
   255             self.ui.warn(_('%s: unsupported file type (type is %s)\n') % (
       
   256                 util.pathto(self.getcwd(), f),
       
   257                 kind))
       
   258         return False
       
   259 
   244     def statwalk(self, files=None, match=util.always, dc=None):
   260     def statwalk(self, files=None, match=util.always, dc=None):
   245         self.read()
   261         self.read()
   246 
   262 
   247         # walk all files by default
   263         # walk all files by default
   248         if not files:
   264         if not files:
   276     #
   292     #
   277     # dc is an optional arg for the current dirstate.  dc is not modified
   293     # dc is an optional arg for the current dirstate.  dc is not modified
   278     # directly by this function, but might be modified by your statmatch call.
   294     # directly by this function, but might be modified by your statmatch call.
   279     #
   295     #
   280     def walkhelper(self, files, statmatch, dc):
   296     def walkhelper(self, files, statmatch, dc):
   281         def supported_type(f, st):
       
   282             if stat.S_ISREG(st.st_mode):
       
   283                 return True
       
   284             else:
       
   285                 kind = 'unknown'
       
   286                 if stat.S_ISCHR(st.st_mode): kind = _('character device')
       
   287                 elif stat.S_ISBLK(st.st_mode): kind = _('block device')
       
   288                 elif stat.S_ISFIFO(st.st_mode): kind = _('fifo')
       
   289                 elif stat.S_ISLNK(st.st_mode): kind = _('symbolic link')
       
   290                 elif stat.S_ISSOCK(st.st_mode): kind = _('socket')
       
   291                 elif stat.S_ISDIR(st.st_mode): kind = _('directory')
       
   292                 self.ui.warn(_('%s: unsupported file type (type is %s)\n') % (
       
   293                     util.pathto(self.getcwd(), f),
       
   294                     kind))
       
   295                 return False
       
   296 
       
   297         # recursion free walker, faster than os.walk.
   297         # recursion free walker, faster than os.walk.
   298         def findfiles(s):
   298         def findfiles(s):
   299             retfiles = []
   299             retfiles = []
   300             work = [s]
   300             work = [s]
   301             while work:
   301             while work:
   314                     st = os.lstat(p)
   314                     st = os.lstat(p)
   315                     if stat.S_ISDIR(st.st_mode):
   315                     if stat.S_ISDIR(st.st_mode):
   316                         ds = os.path.join(nd, f +'/')
   316                         ds = os.path.join(nd, f +'/')
   317                         if statmatch(ds, st):
   317                         if statmatch(ds, st):
   318                             work.append(p)
   318                             work.append(p)
   319                     elif statmatch(np, st) and supported_type(np, st):
   319                         if statmatch(np, st) and np in dc:
   320                         yield util.pconvert(np), st
   320                             yield 'm', util.pconvert(np), st
   321 
   321                     elif statmatch(np, st):
       
   322                         if self.supported_type(np, st):
       
   323                             yield 'f', util.pconvert(np), st
       
   324                         elif np in dc:
       
   325                             yield 'm', util.pconvert(np), st
   322 
   326 
   323         known = {'.hg': 1}
   327         known = {'.hg': 1}
   324         def seen(fn):
   328         def seen(fn):
   325             if fn in known: return True
   329             if fn in known: return True
   326             known[fn] = 1
   330             known[fn] = 1
   335                 if ff not in dc: self.ui.warn('%s: %s\n' % (
   339                 if ff not in dc: self.ui.warn('%s: %s\n' % (
   336                     util.pathto(self.getcwd(), ff),
   340                     util.pathto(self.getcwd(), ff),
   337                     inst.strerror))
   341                     inst.strerror))
   338                 continue
   342                 continue
   339             if stat.S_ISDIR(st.st_mode):
   343             if stat.S_ISDIR(st.st_mode):
   340                 cmp0 = (lambda x, y: cmp(x[0], y[0]))
   344                 cmp1 = (lambda x, y: cmp(x[1], y[1]))
   341                 sorted = [ x for x in findfiles(f) ]
   345                 sorted = [ x for x in findfiles(f) ]
   342                 sorted.sort(cmp0)
   346                 sorted.sort(cmp1)
   343                 for fl, stl in sorted:
   347                 for e in sorted:
   344                     yield 'f', fl, stl
   348                     yield e
   345             else:
   349             else:
   346                 ff = util.normpath(ff)
   350                 ff = util.normpath(ff)
   347                 if seen(ff):
   351                 if seen(ff):
   348                     continue
   352                     continue
   349                 found = False
       
   350                 self.blockignore = True
   353                 self.blockignore = True
   351                 if statmatch(ff, st) and supported_type(ff, st):
   354                 if statmatch(ff, st):
   352                     found = True
   355                     if self.supported_type(ff, st):
       
   356                         yield 'f', ff, st
       
   357                     elif ff in dc:
       
   358                         yield 'm', ff, st
   353                 self.blockignore = False
   359                 self.blockignore = False
   354                 if found:
       
   355                     yield 'f', ff, st
       
   356 
   360 
   357         # step two run through anything left in the dc hash and yield
   361         # step two run through anything left in the dc hash and yield
   358         # if we haven't already seen it
   362         # if we haven't already seen it
   359         ks = dc.keys()
   363         ks = dc.keys()
   360         ks.sort()
   364         ks.sort()
   371                 type, mode, size, time = self[fn]
   375                 type, mode, size, time = self[fn]
   372             except KeyError:
   376             except KeyError:
   373                 unknown.append(fn)
   377                 unknown.append(fn)
   374                 continue
   378                 continue
   375             if src == 'm':
   379             if src == 'm':
   376                 try:
   380                 nonexistent = True
   377                     st = os.stat(fn)
   381                 if not st:
   378                 except OSError, inst:
   382                     try:
       
   383                         st = os.lstat(fn)
       
   384                     except OSError, inst:
       
   385                         if inst.errno != errno.ENOENT:
       
   386                             raise
       
   387                         st = None
       
   388                     # We need to re-check that it is a valid file
       
   389                     if st and self.supported_type(fn, st):
       
   390                         nonexistent = False
   379                 # XXX: what to do with file no longer present in the fs
   391                 # XXX: what to do with file no longer present in the fs
   380                 # who are not removed in the dirstate ?
   392                 # who are not removed in the dirstate ?
   381                     if inst.errno != errno.ENOENT:
   393                 if nonexistent:
   382                         raise
       
   383                     deleted.append(fn)
   394                     deleted.append(fn)
   384                     continue
   395                     continue
   385             # check the common case first
   396             # check the common case first
   386             if type == 'n':
   397             if type == 'n':
   387                 if not st:
   398                 if not st: