Rename a file's capitalisation on Windows or macOS
I renamed a file's case and Git won't notice — how do I fix it?
Short answer
Windows and macOS filesystems treat Player.cs and player.cs as the same file, so a case-only rename is invisible to Git. Use git mv -f to force it, or rename via a temporary name, then commit — otherwise the wrong case ships to your Linux CI and the build breaks.
git mv --force player.cs Player.cs
Forces Git to record a case-only rename
Does this match your situation?
- You renamed a file's capitalisation and git status shows nothing.
- Imports fail on Linux or in CI but work locally.
- Both PascalCase and lowercase versions appear on GitHub.
- A colleague on Linux sees duplicate files.
Step-by-step fix
Force the rename through Git
git mv writes both the deletion and the addition into the index even when the filesystem considers them identical. This is the one-command fix.
step 1git mv --force player.cs Player.cs git status git commit -m "Fix filename capitalisation"Or rename through an intermediate name
If git mv refuses, two renames sidestep the filesystem's case-insensitivity entirely.
step 2git mv player.cs temp-name.cs git commit -m "Temporary rename" git mv temp-name.cs Player.cs git commit -m "Rename to Player.cs"Fix a duplicate that already reached the remote
If both cases are now tracked, remove the wrong one explicitly from the index and commit that.
step 3git ls-files | grep -i player.cs # shows both if duplicated git rm --cached player.cs git commit -m "Remove duplicate lowercase filename" git pushShow the PowerShell (Windows) version
PowerShell (Windows)git ls-files | Select-String -Pattern "player.cs" -CaseSensitive:$false git rm --cached player.cs git commit -m "Remove duplicate lowercase filename"Make Git case-sensitive in this repository
Turning off ignorecase makes Git notice case differences itself, at the cost of some odd behaviour on a case-insensitive filesystem. Useful while cleaning up a mess.
step 4git config core.ignorecase false git statusLeave this off for everyday work on Windows/macOS - it can produce confusing duplicate-path states.
Verify the fix from a case-sensitive point of view
The index is the truth. Check what Git actually has recorded rather than what the filesystem shows you.
step 5git ls-tree -r HEAD --name-only | grep -i player
Why this works
Git's index stores exact byte-for-byte pathnames and is fully case-sensitive, but NTFS and APFS are not — so when you rename a file's case, the operating system reports the same path back and Git sees nothing to record. On a case-sensitive filesystem like the one your Linux CI runs, the old and new names are genuinely different files, which is why the mismatch only surfaces there. Forcing the rename writes the correct path into the index regardless of what the filesystem thinks.
How to stop it happening again
- Agree a naming convention and enforce it in code review.
- Add a CI check that fails when two tracked paths differ only by case.
- Use git mv rather than your editor or file explorer for renames.
Commands used in this guide
git mvRename or move a file and stage the change in one step.
git rmDelete a file from the repository - or just stop tracking it.
git configRead and write Git settings for one repo, your user, or the whole machine.
git ls-filesList files in the index, with precise filters for state.
git ls-treeList the contents of a tree object at any commit.
Still stuck?
Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.
Browse all guides →Frequently asked questions
Why doesn't Git detect my filename case change?
Because Windows and macOS filesystems are case-insensitive, so renaming Player.cs to player.cs leaves the same path as far as the OS is concerned. Git's index is case-sensitive, but it never sees a change to record. git mv --force writes it explicitly.
How do I fix a file committed with the wrong capitalisation?
git mv --force oldname newname, then commit. If both cases somehow got committed, remove the wrong one with git rm --cached and commit that too, then have everyone re-pull.
Should I set core.ignorecase false?
Only temporarily, while sorting out a case problem. Left on permanently on a case-insensitive filesystem it produces confusing states where Git believes two files exist and the OS disagrees.
Related rescue guides
git status says every file changed but I didn't touch them — how do I fix line endings?
Windows writes CRLF and Unix writes LF, and without a policy Git records whichever your editor produced. Commit a .gitattributes with `* text=auto`, then renormalise the repository once — this fixes it for everyone, unlike the per-machine core.autocrlf setting.
Read the fix →Always fixableWhy is .gitignore not working for files that are already tracked?
.gitignore only applies to untracked files. Once a file has been committed, Git keeps tracking it no matter what the ignore rules say. Remove it from the index with git rm --cached <file> — that stops tracking while leaving the file on your disk.
Read the fix →Always fixableI ran git rm and deleted a file — how do I restore it?
If you haven't committed the deletion, git restore --staged --worktree <file> brings the file back from HEAD. If you already committed, restore it from the previous commit with git restore --source=HEAD~1.
Read the fix →Always fixableGit says files changed but only the mode differs — how do I ignore that?
Git tracks the executable bit, so a file going from 100644 to 100755 counts as a change. Set core.fileMode false to ignore mode differences, or fix the bit properly with git update-index --chmod when it genuinely matters.
Read the fix →