[PATCH 2 of 2] dirstate: normalize on case insensitive filesystems on Mac (issue1663)
Matt Mackall
mpm at selenic.com
Sat Jul 25 11:07:00 CDT 2009
On Fri, 2009-07-24 at 23:37 +0200, Dan Villiom Podlaski Christiansen
wrote:
> # HG changeset patch
> # User Dan Villiom Podlaski Christiansen <danchr at gmail.com>
> # Date 1248470961 -7200
> # Node ID f132b7058ffa2d3b4a544fe4ded53ac7e35a26ac
> # Parent d98cef25b5afed5d8aa325ef87f98789367d8b6e
> util: add normalizepath() for getting the 'true' path on Mac OS X.
This looks promising. Please make it two patches: first introduce
realpath, next update dirstate.py.
Linux has something roughly equivalent to F_GETPATH: /proc/[pid]/fd/[fd]
is a symlink to the file in question. Not sure if it reflects case
folding on VFAT/NTFS/HFS+ though.
> diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
> --- a/mercurial/dirstate.py
> +++ b/mercurial/dirstate.py
> @@ -59,7 +59,7 @@ class dirstate(object):
> def _foldmap(self):
> f = {}
> for name in self._map:
> - f[os.path.normcase(name)] = name
> + f[util.realpath(name)] = name
> return f
>
> @propertycache
> @@ -340,7 +340,7 @@ class dirstate(object):
> self._ui.warn(_("not in dirstate: %s\n") % f)
>
> def _normalize(self, path, knownpath):
> - norm_path = os.path.normcase(path)
> + norm_path = util.realpath(path)
> fold_path = self._foldmap.get(norm_path, None)
Your patch has some whitespace damage.
> if fold_path is None:
> if knownpath or not
> os.path.exists(os.path.join(self._root, path)):
> diff --git a/mercurial/posix.py b/mercurial/posix.py
> --- a/mercurial/posix.py
> +++ b/mercurial/posix.py
> @@ -7,7 +7,7 @@
>
> from i18n import _
> import osutil
> -import os, sys, errno, stat, getpass, pwd, grp
> +import os, sys, errno, stat, getpass, pwd, grp, fcntl
>
> posixfile = open
> nulldev = '/dev/null'
> @@ -104,6 +104,19 @@ def pconvert(path):
> def localpath(path):
> return path
>
> +if sys.platform == 'darwin':
> + def realpath(path):
> + try:
> + # fcntl.h: O_SYMLINK = 0x200000, F_GETPATH = 50
> + f = os.open(path, 0x200000)
> + r = fcntl.fcntl(f, 50, '\0' * 1024)
> + os.close(f)
> + return r.rstrip('\0')
> + except IOError:
> + return path
> +else:
> + realpath = os.path.realpath
> +
This probably deserves a comment about the silliness we're addressing.
> def shellquote(s):
> if os.sys.platform == 'OpenVMS':
> return '"%s"' % s
> diff --git a/mercurial/windows.py b/mercurial/windows.py
> --- a/mercurial/windows.py
> +++ b/mercurial/windows.py
> @@ -126,6 +126,10 @@ def localpath(path):
> def normpath(path):
> return pconvert(os.path.normpath(path))
>
> +def realpath(path):
> + '''Obtain the canonical version of a path.'''
> + return os.path.normpath(os.path.normcase(os.path.realpath(path)))
> +
> def samestat(s1, s2):
> return False
--
http://selenic.com : development and support for Mercurial and Linux
More information about the Mercurial-devel
mailing list