mercurial/pathutil.py
changeset 26587 56b2bcea2529
parent 25964 d740df4e96cf
child 27231 6d29ce250a3d
equal deleted inserted replaced
26586:d51c658d3f04 26587:56b2bcea2529
     6 import stat
     6 import stat
     7 
     7 
     8 from .i18n import _
     8 from .i18n import _
     9 from . import (
     9 from . import (
    10     encoding,
    10     encoding,
       
    11     error,
    11     util,
    12     util,
    12 )
    13 )
    13 
    14 
    14 def _lowerclean(s):
    15 def _lowerclean(s):
    15     return encoding.hfsignoreclean(s.lower())
    16     return encoding.hfsignoreclean(s.lower())
    45         normpath = self.normcase(path)
    46         normpath = self.normcase(path)
    46         if normpath in self.audited:
    47         if normpath in self.audited:
    47             return
    48             return
    48         # AIX ignores "/" at end of path, others raise EISDIR.
    49         # AIX ignores "/" at end of path, others raise EISDIR.
    49         if util.endswithsep(path):
    50         if util.endswithsep(path):
    50             raise util.Abort(_("path ends in directory separator: %s") % path)
    51             raise error.Abort(_("path ends in directory separator: %s") % path)
    51         parts = util.splitpath(path)
    52         parts = util.splitpath(path)
    52         if (os.path.splitdrive(path)[0]
    53         if (os.path.splitdrive(path)[0]
    53             or _lowerclean(parts[0]) in ('.hg', '.hg.', '')
    54             or _lowerclean(parts[0]) in ('.hg', '.hg.', '')
    54             or os.pardir in parts):
    55             or os.pardir in parts):
    55             raise util.Abort(_("path contains illegal component: %s") % path)
    56             raise error.Abort(_("path contains illegal component: %s") % path)
    56         # Windows shortname aliases
    57         # Windows shortname aliases
    57         for p in parts:
    58         for p in parts:
    58             if "~" in p:
    59             if "~" in p:
    59                 first, last = p.split("~", 1)
    60                 first, last = p.split("~", 1)
    60                 if last.isdigit() and first.upper() in ["HG", "HG8B6C"]:
    61                 if last.isdigit() and first.upper() in ["HG", "HG8B6C"]:
    61                     raise util.Abort(_("path contains illegal component: %s")
    62                     raise error.Abort(_("path contains illegal component: %s")
    62                                      % path)
    63                                      % path)
    63         if '.hg' in _lowerclean(path):
    64         if '.hg' in _lowerclean(path):
    64             lparts = [_lowerclean(p.lower()) for p in parts]
    65             lparts = [_lowerclean(p.lower()) for p in parts]
    65             for p in '.hg', '.hg.':
    66             for p in '.hg', '.hg.':
    66                 if p in lparts[1:]:
    67                 if p in lparts[1:]:
    67                     pos = lparts.index(p)
    68                     pos = lparts.index(p)
    68                     base = os.path.join(*parts[:pos])
    69                     base = os.path.join(*parts[:pos])
    69                     raise util.Abort(_("path '%s' is inside nested repo %r")
    70                     raise error.Abort(_("path '%s' is inside nested repo %r")
    70                                      % (path, base))
    71                                      % (path, base))
    71 
    72 
    72         normparts = util.splitpath(normpath)
    73         normparts = util.splitpath(normpath)
    73         assert len(parts) == len(normparts)
    74         assert len(parts) == len(normparts)
    74 
    75 
    88                 # They must be ignored for patterns can be checked too.
    89                 # They must be ignored for patterns can be checked too.
    89                 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
    90                 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
    90                     raise
    91                     raise
    91             else:
    92             else:
    92                 if stat.S_ISLNK(st.st_mode):
    93                 if stat.S_ISLNK(st.st_mode):
    93                     raise util.Abort(
    94                     raise error.Abort(
    94                         _('path %r traverses symbolic link %r')
    95                         _('path %r traverses symbolic link %r')
    95                         % (path, prefix))
    96                         % (path, prefix))
    96                 elif (stat.S_ISDIR(st.st_mode) and
    97                 elif (stat.S_ISDIR(st.st_mode) and
    97                       os.path.isdir(os.path.join(curpath, '.hg'))):
    98                       os.path.isdir(os.path.join(curpath, '.hg'))):
    98                     if not self.callback or not self.callback(curpath):
    99                     if not self.callback or not self.callback(curpath):
    99                         raise util.Abort(_("path '%s' is inside nested "
   100                         raise error.Abort(_("path '%s' is inside nested "
   100                                            "repo %r")
   101                                            "repo %r")
   101                                          % (path, prefix))
   102                                          % (path, prefix))
   102             prefixes.append(normprefix)
   103             prefixes.append(normprefix)
   103             parts.pop()
   104             parts.pop()
   104             normparts.pop()
   105             normparts.pop()
   110 
   111 
   111     def check(self, path):
   112     def check(self, path):
   112         try:
   113         try:
   113             self(path)
   114             self(path)
   114             return True
   115             return True
   115         except (OSError, util.Abort):
   116         except (OSError, error.Abort):
   116             return False
   117             return False
   117 
   118 
   118 def canonpath(root, cwd, myname, auditor=None):
   119 def canonpath(root, cwd, myname, auditor=None):
   119     '''return the canonical path of myname, given cwd and root'''
   120     '''return the canonical path of myname, given cwd and root'''
   120     if util.endswithsep(root):
   121     if util.endswithsep(root):
   165         try:
   166         try:
   166             if cwd != root:
   167             if cwd != root:
   167                 canonpath(root, root, myname, auditor)
   168                 canonpath(root, root, myname, auditor)
   168                 hint = (_("consider using '--cwd %s'")
   169                 hint = (_("consider using '--cwd %s'")
   169                         % os.path.relpath(root, cwd))
   170                         % os.path.relpath(root, cwd))
   170         except util.Abort:
   171         except error.Abort:
   171             pass
   172             pass
   172 
   173 
   173         raise util.Abort(_("%s not under root '%s'") % (myname, root),
   174         raise error.Abort(_("%s not under root '%s'") % (myname, root),
   174                          hint=hint)
   175                          hint=hint)
   175 
   176 
   176 def normasprefix(path):
   177 def normasprefix(path):
   177     '''normalize the specified path as path prefix
   178     '''normalize the specified path as path prefix
   178 
   179