Simulating case collisions on Linux
Matt Mackall
mpm at selenic.com
Fri Jun 24 05:33:43 UTC 2011
This evening I've been playing a bit with trying to emulate Windows'
case folding behavior on Linux by making an extension that tweaks
Mercurial's interface to the filesystem. Here's what I've come up with:
---------
diff -r b9faf94ee196 contrib/casesmash.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/casesmash.py Fri Jun 24 00:23:31 2011 -0500
@@ -0,0 +1,34 @@
+import sys, os, __builtin__
+from mercurial import util
+
+def lowerwrap(scope, funcname):
+ f = getattr(scope, funcname)
+ def wrap(fname, *args, **kwargs):
+ d, base = os.path.split(fname)
+ try:
+ files = os.listdir(d or '.')
+ except OSError, inst:
+ files = []
+ if base in files:
+ return f(fname, *args, **kwargs)
+ for fn in files:
+ if fn.lower() == base.lower():
+ return f(os.path.join(d, fn), *args, **kwargs)
+ return f(fname, *args, **kwargs)
+ scope.__dict__[funcname] = wrap
+
+def normcase(path):
+ return path.lower()
+
+os.path.normcase = normcase
+
+for f in 'file open'.split():
+ lowerwrap(__builtin__, f)
+
+for f in "chmod chown open lstat stat remove unlink".split():
+ lowerwrap(os, f)
+
+for f in "exists lexists".split():
+ lowerwrap(os.path, f)
+
+lowerwrap(util, 'posixfile')
---------------
This works well enough that a simple test case like this:
hg init a
cd a
echo b > B
hg ci -qAm0
hg co -q null
echo b > b
hg ci -qAm1
hg merge -q
hg ci -qm2
hg up -C .
...can accurately reproduce a Windows case collision bug.
We can probably use something like this in the test suite. It's also
probably a simple matter to make an extension that emulates Windows
no-exec-bit behavior as well.
(This all turns out to be significantly less painful than trying to do
development under Wine, due to being only a partial Windows emulation)
--
Mathematics is the supreme nostalgia of our time.
More information about the Mercurial-devel
mailing list