cygwin: add cygwin specific normcase logic
authorFUJIWARA Katsunori <foozy@lares.dti.ne.jp>
Fri, 16 Dec 2011 21:21:08 +0900
changeset 15711 c51c9dc13a58
parent 15710 f63e40047372
child 15712 06b8b74720d6
cygwin: add cygwin specific normcase logic in cygwin environment, mount point part of path is treated as case sensitive, even though underlying NTFS is case insensitive. this patch preserves mount point part of specified path, only if it is absolute one. there is no easy way to get list of current mount points from python program, other than to execute "mount" external command, because cygwin does not store current mount points into Unix/Linux like /etc/XXXtab file. so, this patch introduces cygwinmountpoints variable to list mount points to be preserved case. this allows some other extensions to customize mount point configuration.
mercurial/posix.py
--- a/mercurial/posix.py	Fri Dec 16 21:09:40 2011 +0900
+++ b/mercurial/posix.py	Fri Dec 16 21:21:08 2011 +0900
@@ -238,6 +238,38 @@
     # Fallback to the likely inadequate Python builtin function.
     realpath = os.path.realpath
 
+if sys.platform == 'cygwin':
+    # workaround for cygwin, in which mount point part of path is
+    # treated as case sensitive, even though underlying NTFS is case
+    # insensitive.
+
+    # default mount points
+    cygwinmountpoints = sorted([
+            "/usr/bin",
+            "/usr/lib",
+            "/cygdrive",
+            ], reverse=True)
+
+    # use upper-ing as normcase as same as NTFS workaround
+    def normcase(path):
+        pathlen = len(path)
+        if (pathlen == 0) or (path[0] != os.sep):
+            # treat as relative
+            return encodingupper(path)
+
+        # to preserve case of mountpoint part
+        for mp in cygwinmountpoints:
+            if not path.startswith(mp):
+                continue
+
+            mplen = len(mp)
+            if mplen == pathlen: # mount point itself
+                return mp
+            if path[mplen] == os.sep:
+                return mp + encodingupper(path[mplen:])
+
+        return encodingupper(path)
+
 def shellquote(s):
     if os.sys.platform == 'OpenVMS':
         return '"%s"' % s