add: notify when adding a file that would cause a case-folding collision
On a case-sensitive file system, files can be added with names that differ
only in case (a "case collision"). This would cause an error on case-insensitive
filesystems. A warning or error is now given for such collisions, depending on
the value of ui.portablefilenames ('warn', 'abort', or 'ignore'):
$ touch file File
$ hg add --config ui.portablefilenames=abort File
abort: possible case-folding collision for File
$ hg add File
warning: possible case-folding collision for File
--- a/mercurial/cmdutil.py Sat Apr 30 11:08:24 2011 +0200
+++ b/mercurial/cmdutil.py Sat Apr 30 12:39:46 2011 +0200
@@ -1314,9 +1314,16 @@
match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
names = []
wctx = repo[None]
+ wctx.status(clean=True)
+ existing = None
+ if scmutil.showportabilityalert(ui):
+ existing = dict([(fn.lower(), fn) for fn in
+ wctx.added() + wctx.clean() + wctx.modified()])
for f in repo.walk(match):
exact = match.exact(f)
if exact or f not in repo.dirstate:
+ if existing:
+ scmutil.checkcasecollision(ui, f, existing)
names.append(f)
if ui.verbose or not exact:
ui.status(_('adding %s\n') % match.rel(join(f)))
--- a/mercurial/scmutil.py Sat Apr 30 11:08:24 2011 +0200
+++ b/mercurial/scmutil.py Sat Apr 30 12:39:46 2011 +0200
@@ -22,6 +22,11 @@
if msg:
portabilityalert(ui, "%s: %r" % (msg, f))
+def checkcasecollision(ui, f, files):
+ if f.lower() in files and files[f.lower()] != f:
+ portabilityalert(ui, _('possible case-folding collision for %s') % f)
+ files[f.lower()] = f
+
def checkportabilityalert(ui):
'''check if the user's config requests nothing, a warning, or abort for
non-portable filenames'''
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-casecollision.t Sat Apr 30 12:39:46 2011 +0200
@@ -0,0 +1,34 @@
+run only on case-sensitive filesystems
+
+ $ "$TESTDIR/hghave" no-icasefs || exit 80
+
+test file addition with colliding case
+
+ $ hg init repo1
+ $ cd repo1
+ $ echo a > a
+ $ echo A > A
+ $ hg add a
+ $ hg st
+ A a
+ ? A
+ $ hg add --config ui.portablefilenames=abort A
+ abort: possible case-folding collision for A
+ [255]
+ $ hg st
+ A a
+ ? A
+ $ hg add A
+ warning: possible case-folding collision for A
+ $ hg st
+ A A
+ A a
+ $ hg forget A
+ $ hg st
+ A a
+ ? A
+ $ hg add --config ui.portablefilenames=no A
+ $ hg st
+ A A
+ A a
+ $ cd ..