Git status shows no changes after renaming 'file.txt' to 'File.txt' on Windows/macOS

beginner๐Ÿ“ฆ Git2026-04-21| Git on Windows (NTFS) and macOS (HFS+/APFS default case-insensitive), Git 2.x

Error Message

git status shows no changes after renaming 'file.txt' to 'File.txt' on Windows/macOS
#git#case-sensitive#rename#config

The Problem

You renamed utils.js to Utils.js โ€” one capital letter. Run git status: nothing. Git acts like it never happened.

Locally, everything works. Then you push to a Linux CI server and the build breaks โ€” imports fail because the server looks for Utils.js but the repo still has utils.js. Classic case of a bug that hides locally and bites you in production.

Why This Happens

Windows (NTFS) and macOS (HFS+/APFS in default configuration) use case-insensitive filesystems. To the OS, file.txt and File.txt are the same file. Since Git relies on the filesystem to detect changes, it never sees a difference.

There's also a Git config option in the mix: core.ignoreCase. On Windows and macOS, Git sets this to true automatically at install time. That's intentional โ€” it prevents false positives on case-insensitive systems. But it also means Git will silently skip real case renames.

Linux is different. Its filesystems are case-sensitive, so file.txt and File.txt are two distinct files. When your code runs on Linux โ€” servers, Docker containers, GitHub Actions โ€” it looks for the exact filename from the repo. If Git never tracked the rename, the old casing is still there, and references break.

Fix 1: Use git mv with a Temporary Name (Recommended)

Rename through a throwaway intermediate name. This tricks Git into recording two separate renames instead of one invisible one.

# Step 1: Rename to a temporary name
git mv utils.js utils_temp.js

# Step 2: Rename from temp to the final name
git mv utils_temp.js Utils.js

# Step 3: Verify Git tracked it
git status

The staging area should now show:

Changes to be committed:
  renamed:    utils.js -> Utils.js
# Step 4: Commit
git commit -m "Rename utils.js to Utils.js"

Fix 2: Set core.ignoreCase = false and Force-Rename

Another option โ€” flip Git into case-sensitive mode just for this operation:

# Make Git case-sensitive for this repo
git config core.ignoreCase false

# Now do the rename directly
git mv utils.js Utils.js

git status

After committing, you can leave core.ignoreCase false or flip it back. Fair warning: leaving it as false on a case-insensitive filesystem sometimes causes Git to report phantom changes on unmodified files. Fix 1 avoids that entirely.

# Optional: revert the config after committing
git config core.ignoreCase true

Fix 3: Already Committed with the Wrong Case?

If the file was already committed and pushed with the wrong casing, the index needs to be updated directly:

# Remove the old file from Git's index (not from disk)
git rm --cached utils.js

# Add the file under the correct new name
git add Utils.js

# Commit the fix
git commit -m "Fix: rename utils.js to Utils.js (case correction)"

If Git complains that the file doesn't exist, try the nuclear option โ€” re-index everything:

# On macOS/Windows when the file shows no changes:
git rm -r --cached .
git add .
git commit -m "Fix file casing in Git index"

Warning: git rm -r --cached . unstages everything and re-adds it. Your actual files are untouched โ€” this only affects the Git index. Still, run git status before committing to catch any unrelated files you don't want to include.

Verification: Confirm the Fix Worked

Check that the rename shows up correctly in the last commit:

# Check the latest commit shows the rename
git log --oneline --name-status -1

Expected output:

a3f9c12 Rename utils.js to Utils.js
R100    utils.js    Utils.js

R100 means Git recorded a rename with 100% similarity. Seeing D (deleted) and A (added) instead isn't ideal, but it still works โ€” the file will exist with the correct name on Linux after a fresh clone.

Push and verify on the remote:

git push origin main

# Then check GitHub/GitLab โ€” the file should now show the new casing

Prevention: Add a Git Alias for Case Renames

Rename files by case regularly? Add this alias to your global config once and forget about the two-step dance:

git config --global alias.mvcased '!f() { git mv "$1" "${1}_tmp" && git mv "${1}_tmp" "$2"; }; f'

Usage:

git mvcased utils.js Utils.js

Quick Reference

  • Scenario 1 โ€” File not yet committed: git mv file.txt temp.txt && git mv temp.txt File.txt
  • Scenario 2 โ€” Committed, not pushed: Set core.ignoreCase false, use git mv, then reset the config
  • Scenario 3 โ€” Already pushed: git rm --cached oldname + git add newname + commit + push
  • Scenario 4 โ€” Multiple files affected: git rm -r --cached . && git add . to re-index everything

Related Error Notes