libgit2/libgit2 — pull request #2341 by ethomson (2014-05-10 02:42:50+00:00)
Title: Checkout case changing renames

On a case insensitive filesystem, we always checkout using a case insensitive iterator, so we end up with a delta that contains (for example) old file: `readme` and new file: `README`. This is treated as a modification of the same file. Instead, we should treat this as a remove of the old name and an add of the new name. If we do not update the index and working directory with the new name, we think that we are (rightly) different from the `HEAD` tree.

For example, I'm on the `master` branch, which contains a file `Foo.txt`: I `git_checkout_tree` a different branch, which renamed this file to `FOO.txt`. Neither the index or working directory are updated:

```
C:\Temp\TestRepo>dir
Volume in drive C is ethomson-t430s
Volume Serial Number is 8E09-4C48

Directory of C:\Temp\TestRepo

05/09/2014 07:39 PM .
05/09/2014 07:39 PM ..
05/09/2014 07:38 PM 6 Foo.txt
1 File(s) 6 bytes
2 Dir(s) 159,162,114,048 bytes free

C:\Temp\TestRepo>git ls-files --stage
100644 b4a3ed0e1a5cf987598e8bf4ebe3f64baa8a20c9 0 Foo.txt

C:\Temp\TestRepo>git status
On branch branch
Changes to be committed:
(use "git reset HEAD ..." to unstage)

renamed: FOO.txt -> Foo.txt
```

The first commit is a test for this behavior. The second commit is a fairly heavy-handed approach to fixing, which simply always checks out case-sensitively. I suspect this is not the way we want to fix this, but I threw it out there to start a discussion.

/cc @arrbee