diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py index 415709a43e54efe6b158c4a38574173f9640847e_bWVyY3VyaWFsL2RpcnN0YXRlLnB5..85785cd3b69f09f2e6ffa78dac75d68d08e400bd_bWVyY3VyaWFsL2RpcnN0YXRlLnB5 100644 --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -730,6 +730,34 @@ else: badfn(ff, inst.strerror) + # Case insensitive filesystems cannot rely on lstat() failing to detect + # a case-only rename. Prune the stat object for any file that does not + # match the case in the filesystem, if there are multiple files that + # normalize to the same path. + if match.isexact() and self._checkcase: + normed = {} + + for f, st in results.iteritems(): + if st is None: + continue + + nc = util.normcase(f) + paths = normed.get(nc) + + if paths is None: + paths = set() + normed[nc] = paths + + paths.add(f) + + for norm, paths in normed.iteritems(): + if len(paths) > 1: + for path in paths: + folded = self._discoverpath(path, norm, True, None, + self._dirfoldmap) + if path != folded: + results[path] = None + return results, dirsfound, dirsnotfound def walk(self, match, subrepos, unknown, ignored, full=True): diff --git a/tests/test-casefolding.t b/tests/test-casefolding.t index 415709a43e54efe6b158c4a38574173f9640847e_dGVzdHMvdGVzdC1jYXNlZm9sZGluZy50..85785cd3b69f09f2e6ffa78dac75d68d08e400bd_dGVzdHMvdGVzdC1jYXNlZm9sZGluZy50 100644 --- a/tests/test-casefolding.t +++ b/tests/test-casefolding.t @@ -143,6 +143,24 @@ $ hg update -q -C 3 $ hg update -q 0 + $ hg up -C -r 2 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg mv A a + $ hg diff -g > rename.diff + $ hg ci -m 'A -> a' + $ hg up -q '.^' + $ hg import rename.diff -m "import rename A -> a" + applying rename.diff + $ hg st + ? rename.diff + $ hg files + a + $ find * | sort + a + rename.diff + + $ rm rename.diff + $ cd .. issue 3342: file in nested directory causes unexpected abort