# Git - Path Case Sensitivity on macOS
macOS filesystems such as APFS are case-insensitive by default, but git pathspecs and the git index stay case-sensitive. As a result, an edit can land on disk while `git add` and the commit silently miss it. Automated bulk edits repeat the trap when tooling derives paths from the filesystem instead of from git.
## Key points
- Git matches pathspecs case-sensitively against the index, even on a case-insensitive filesystem. The index stores one canonical casing. `git add projects/Work/file.md` silently stages nothing when git records the path as `projects/work/file.md`.
- `git ls-files` reveals the tracked casing. The filesystem can show `projects/Work/` while git tracks `projects/work/`. Stage and commit with the tracked spelling, not with the displayed one.
- A case-mismatched `git add` no-ops, and a later commit ships whatever was already staged. Check the tracked casing before you declare an edited file untracked.
- A status check has the same trap. A check with the displayed casing `projects/Work/` misses a file that git indexes as `projects/work/`, so `git diff` looks empty after a successful write. Two independent automated runs hit this in one day.
- `core.ignorecase` lets case-only renames escape history. The index and the filesystem can permanently disagree on the canonical path. Tooling that derives paths from the filesystem then disagrees with git.
- Case-only renames resurface during bulk automated edits. In one run, git resolved the path with `projects/work/` while the tooling resolved the same path with `projects/Work/`.
## How to apply
Before you stage or commit a path on macOS:
1. Show the tracked casing: `git ls-files | grep -i <path>`.
2. Stage with the exact spelling that `git ls-files` returns: `git add projects/work/<file>`.
3. Treat a silent `git add` as a casing problem first. Do not declare the file untracked before you check `git ls-files`.
4. Run `git status` and `git diff` with the tracked casing. An empty diff after a successful write means the pathspec uses the wrong case.
5. In automated edits, resolve paths from `git ls-files`, not from the filesystem. After a case-only rename, verify the tracked path again before you commit.
## Observations
- [git] Pathspecs are matched case-sensitively against the index, so `git add` with the displayed casing can silently stage nothing. #git (source: agent sessions, 2026-07)
- [git] `git ls-files` returns the tracked casing, and the pathspec needs that exact spelling. #git (source: agent sessions, 2026-09)
- [automation] A status check with the wrong casing makes `git diff` look empty after a successful write. Two automated runs hit this in one day. #automation (source: agent sessions, 2026-07)
- [git] `core.ignorecase` lets case-only renames escape history and leaves the index and the filesystem in permanent disagreement. #git (source: agent sessions, 2026-07)
- [automation] Bulk automated edits resurface case-only renames when git and the tooling resolve the same path with different casing. #automation (source: agent sessions, 2026-08)
## Relations
- relates_to [[resources/documentation/Git - Commit Signing with SSH Agents and gitsign]] (one commit flow hit both a case-mismatched add and an SSH signing failure)
- relates_to [[resources/documentation/Git Configuration]] (`core.ignorecase` is a git configuration value)
- relates_to [[resources/documentation/macOS - Developer Environment Pitfalls]] (the case-insensitive macOS filesystem causes the mismatch)
## Sources
- Personal agent-session notes, July 2026 to September 2026