Git Case-Sensitive File Renames on macOS

3 min read

Today I learned the hard way about case-sensitivity issues between macOS and Linux when working with git.

The problem

When I started working on this blog, I was naming component files in title case. Later on I realized that most of the files were in lower case and some in camel case, migrating all files to kebab case looked reasonable and so I went for it.

I had files tracked in git in title case (Badge.tsx, Card.tsx, Title.tsx), so I thought just renaming them (badge.tsx, card.tsx, title.tsx) would be okay:

typescript
// after renaming the files I updated the imports to
import Badge from "@/components/badge";
import Card from "@/components/card";

On macOS: Everything worked fine ✅ In Linux CI: Build failed with "Module not found" ❌

Why this happened

  • Git preserves the original case of filenames unless you explicitly change them, but macOS doesn't care about case differences so things worked locally for me
  • macOS uses a case-insensitive filesystem by default (HFS+/APFS)
  • Linux uses a case-sensitive filesystem (ext4)
  • When CI runs on Linux, the exact case must match

Common mistakes that cause this issue

  • Rename the file in your IDE or terminal and do a git add
bash
# after renaming Badge.tsx to badge.tsx in your IDE or terminal
git add badge.tsx
# Git sees no change because macOS treats them as the same file!
  • Use git mv to rename the files
bash
# This doesn't work on case-insensitive filesystems!
git mv Badge.tsx badge.tsx
# Error: badge.tsx and Badge.tsx are treated as the same file

The right way

Use a two-step rename with a temporary name:

bash
# Step 1: Rename to a temporary name
git mv Badge.tsx badge-temp.tsx

# Step 2: Rename to the final lowercase name
git mv badge-temp.tsx badge.tsx

# Or as a one-liner:
git mv Badge.tsx temp && git mv temp badge.tsx

# Commit the change
git commit -m "fix: rename Badge.tsx to badge.tsx for case-sensitivity"

You are most likely to run into this if you are working in a team with mixed OS environments or if your CI/CD runs on a different OS than your development environment.

You can check which files have mixed cases by using git ls-files:

bash
# List all files tracked by git
git ls-files

# Find files with uppercase letters in components/
git ls-files | grep -E "src/components/.*[A-Z]"

This small detail can save hours of debugging when your local build works but CI mysteriously fails!

Learned about git rebase --onto for moving branches to a different base.

Dec 22, 2025

How to use Next.js's connection() API to opt specific components into dynamic rendering while keeping the rest of your page statically generated.

How to fix Tailwind dark mode colors when prefers-color-scheme conflicts with manual theme toggling.