mercurial/dirstate.py
changeset 48290 91f07430db8c
parent 48282 0d6a099bba58
child 48291 500260410bb8
equal deleted inserted replaced
48288:4216f5561c3b 48290:91f07430db8c
   240         # much faster than os.path.join()
   240         # much faster than os.path.join()
   241         # it's safe because f is always a relative path
   241         # it's safe because f is always a relative path
   242         return self._rootdir + f
   242         return self._rootdir + f
   243 
   243 
   244     def flagfunc(self, buildfallback):
   244     def flagfunc(self, buildfallback):
   245         if not (self._checklink and self._checkexec):
   245         """build a callable that returns flags associated with a filename
   246             fallback = buildfallback()
   246 
   247 
   247         The information is extracted from three possible layers:
   248         def check_both(x):
   248         1. the file system if it supports the information
   249             """This platform supports symlinks and exec permissions"""
   249         2. the "fallback" information stored in the dirstate if any
       
   250         3. a more expensive mechanism inferring the flags from the parents.
       
   251         """
       
   252 
       
   253         # small hack to cache the result of buildfallback()
       
   254         fallback_func = []
       
   255 
       
   256         def get_flags(x):
       
   257             entry = None
       
   258             fallback_value = None
   250             try:
   259             try:
   251                 st = os.lstat(self._join(x))
   260                 st = os.lstat(self._join(x))
       
   261             except OSError:
       
   262                 return b''
       
   263 
       
   264             if self._checklink:
   252                 if util.statislink(st):
   265                 if util.statislink(st):
   253                     return b'l'
   266                     return b'l'
       
   267             else:
       
   268                 entry = self.get_entry(x)
       
   269                 if entry.has_fallback_symlink:
       
   270                     if entry.fallback_symlink:
       
   271                         return b'l'
       
   272                 else:
       
   273                     if not fallback_func:
       
   274                         fallback_func.append(buildfallback())
       
   275                     fallback_value = fallback_func[0](x)
       
   276                     if b'l' in fallback_value:
       
   277                         return b'l'
       
   278 
       
   279             if self._checkexec:
   254                 if util.statisexec(st):
   280                 if util.statisexec(st):
   255                     return b'x'
   281                     return b'x'
   256             except OSError:
   282             else:
   257                 pass
   283                 if entry is None:
       
   284                     entry = self.get_entry(x)
       
   285                 if entry.has_fallback_exec:
       
   286                     if entry.fallback_exec:
       
   287                         return b'x'
       
   288                 else:
       
   289                     if fallback_value is None:
       
   290                         if not fallback_func:
       
   291                             fallback_func.append(buildfallback())
       
   292                         fallback_value = fallback_func[0](x)
       
   293                     if b'x' in fallback_value:
       
   294                         return b'x'
   258             return b''
   295             return b''
   259 
   296 
   260         def check_link(x):
   297         return get_flags
   261             """This platform only supports symlinks"""
       
   262             if os.path.islink(self._join(x)):
       
   263                 return b'l'
       
   264             entry = self.get_entry(x)
       
   265             if entry.has_fallback_exec:
       
   266                 if entry.fallback_exec:
       
   267                     return b'x'
       
   268             elif b'x' in fallback(x):
       
   269                 return b'x'
       
   270             return b''
       
   271 
       
   272         def check_exec(x):
       
   273             """This platform only supports exec permissions"""
       
   274             if b'l' in fallback(x):
       
   275                 return b'l'
       
   276             entry = self.get_entry(x)
       
   277             if entry.has_fallback_symlink:
       
   278                 if entry.fallback_symlink:
       
   279                     return b'l'
       
   280             if util.isexec(self._join(x)):
       
   281                 return b'x'
       
   282             return b''
       
   283 
       
   284         def check_fallback(x):
       
   285             """This platform supports neither symlinks nor exec permissions, so
       
   286             check the fallback in the dirstate if it exists, otherwise figure it
       
   287             out the more expensive way from the parents."""
       
   288             entry = self.get_entry(x)
       
   289             if entry.has_fallback_symlink:
       
   290                 if entry.fallback_symlink:
       
   291                     return b'l'
       
   292             if entry.has_fallback_exec:
       
   293                 if entry.fallback_exec:
       
   294                     return b'x'
       
   295                 elif entry.has_fallback_symlink:
       
   296                     return b''
       
   297             return fallback(x)
       
   298 
       
   299         if self._checklink and self._checkexec:
       
   300             return check_both
       
   301         elif self._checklink:
       
   302             return check_link
       
   303         elif self._checkexec:
       
   304             return check_exec
       
   305         else:
       
   306             return check_fallback
       
   307 
   298 
   308     @propertycache
   299     @propertycache
   309     def _cwd(self):
   300     def _cwd(self):
   310         # internal config: ui.forcecwd
   301         # internal config: ui.forcecwd
   311         forcecwd = self._ui.config(b'ui', b'forcecwd')
   302         forcecwd = self._ui.config(b'ui', b'forcecwd')