# HG changeset patch # User Martin von Zweigbergk # Date 1428209652 25200 # Node ID 1784ca1483921babd792932d1e4575fda1c3359e # Parent e1842ef61edbdb5725112a968adeb9990436c15d dirstate.walk: don't report same file stat multiple times dirstate.walk() generates pairs of filename and a stat-like object. After "hg mv foo Foo", it generates one pair for "foo" and one for "Foo", as it should. However, on case-insensitive file systems, when it tries to stat to get the disk state as well, it gets the same stat result for both names. This confuses at least scmutil._interestingfiles(), making it think that "foo" was forgotten rather than removed. That, in turn, makes "hg addremove" add "foo" back, resulting in both cases in the dirstate, as reported in issue4590. This change only takes care of the "if unknown" branch. A similar fix should perhaps be applied to the other branch. diff -r e1842ef61edb -r 1784ca148392 mercurial/dirstate.py --- a/mercurial/dirstate.py Thu Apr 02 21:29:05 2015 +0900 +++ b/mercurial/dirstate.py Sat Apr 04 21:54:12 2015 -0700 @@ -793,9 +793,15 @@ audit_path = pathutil.pathauditor(self._root) for nf in iter(visit): + # If a stat for the same file was already added with a + # different case, don't add one for this, since that would + # make it appear as if the file exists under both names + # on disk. + if normalize and normalize(nf, True, True) in results: + results[nf] = None # Report ignored items in the dmap as long as they are not # under a symlink directory. - if audit_path.check(nf): + elif audit_path.check(nf): try: results[nf] = lstat(join(nf)) # file was just ignored, no links, and exists diff -r e1842ef61edb -r 1784ca148392 tests/test-casefolding.t --- a/tests/test-casefolding.t Thu Apr 02 21:29:05 2015 +0900 +++ b/tests/test-casefolding.t Sat Apr 04 21:54:12 2015 -0700 @@ -37,6 +37,15 @@ $ hg mv A a $ hg st +addremove after case-changing rename has no effect (issue4590) + + $ hg mv a A + $ hg addremove + recording removal of a as rename to A (100% similar) + $ hg revert --all + forgetting A + undeleting a + test changing case of path components $ mkdir D