[PATCH 1 of 3] Add a new function, filesystem_case

Paul Moore p.f.moore at gmail.com
Tue Apr 22 17:10:54 CDT 2008


# HG changeset patch
# User "Paul Moore <p.f.moore at gmail.com>"
# Date 1208894004 -3600
# Node ID 47aabfeb37f4a12d015b809afef81cb817e18972
# Parent  90becd2b697eb345328dabb08e23262335bf9ff2
Add a new function, filesystem_case

The function, given a filename and an (optional) root, returns the filename
modified to use the case actually stored in the filesystem (if the file does
not exist, return the name unchanged).

An immplementation for Windows (case insensitive) and a no-op implementation
for Unix is given. Unix can potentially have a case insensitive filesystem,
but this implementation doesn't consider that. We also don't consider fancy
stuff like Mac OS X normalisation forms. Suitable implementations for these
can be added later.

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1063,6 +1063,42 @@
     def localpath(path):
         return path.replace('/', '\\')
 
+    def filesystem_case(name, root=''):
+        '''Get name in the case stored in the filesystem
+
+        The filename 'name' is relative to the path 'root' (if given).
+        If the file does not exist, return it unchanged. Otherwise, return the
+        version of name with case as stored in the filesystem.
+        '''
+        if not os.path.exists(os.path.join(root, name)):
+            return name
+        parts = []
+        while name:
+            dir, leaf = os.path.split(name)
+
+            # Scan os.listdir for a name that matches leaf except for case
+            leaf_l = leaf.lower()
+            for n in os.listdir(os.path.join(root, dir)):
+                if n.lower() == leaf_l:
+                    parts.append(n)
+                    break
+            else:
+                # This should never happen, as the file exists so it should
+                # show up in os.listdir. TODO: check if this is needed for
+                # hidden files, but they are probably weird anyway...
+                parts.append(leaf)
+
+            # Get the actual separator used in 'name', as we want to match
+            # whichever of os.sep or os.altsep was used.
+            if dir:
+                sep = name[len(dir)]
+                parts.append(sep)
+
+            name = dir
+
+        parts.reverse()
+        return ''.join(parts)
+
     def normpath(path):
         return pconvert(os.path.normpath(path))
 
@@ -1230,6 +1266,12 @@
         return path
 
     def localpath(path):
+        return path
+
+    def filesystem_case(path, root=''):
+        '''Get name in the case stored in the filesystem.
+        This is a no-op as we assume a case sensitive filesystem on Unix.
+        '''
         return path
 
     normpath = os.path.normpath


More information about the Mercurial-devel mailing list