macOS: grit init omits core.precomposeunicode/ignorecase; grit add stores NFD (decomposed) paths in the index and trees
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 32/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- git, macos, rust
- Domain
- cli, operating-systems
Research direction
Start from how grit init writes .git/config and how grit add records worktree names into the index and trees. Reproduce the given APFS NFD filename vs git init/git add on macOS, then make init probe the filesystem like git (core.precomposeunicode and core.ignorecase) and normalize paths to NFC on add. Done when the tree stores NFC bytes matching git and case collisions are detected; grit clone should set the same keys.
Written by the indexing model from the issue text.
Description
Kind: compat · Severity: high · Area: init / add / index (macOS path handling)
Steps to reproduce
on macOS (APFS)
mkdir /tmp/nfd && cd /tmp/nfd
grit init
git config user.email a@b; git config user.name a
printf 'x\n' > "$(printf 'cafe\xcc\x81.txt')" # decomposed e + U+0301, as created by many macOS tools
grit add && grit commit -m one
git ls-files -z | xxd | head -2
cat .git/config
for comparison
mkdir /tmp/nfd-git && cd /tmp/nfd-git && git init -q && git config user.email a@b && git config user.name a
printf 'x\n' > "$(printf 'cafe\xcc\x81.txt')"
git add -A && git ls-files -z | xxd | head -2
cat .git/config
Reproduced with released grit 0.5.0 and current main (b4bb866f5). grit-git init sets precomposeunicode but not ignorecase; grit clone sets neither.
Expected
git init on macOS probes the filesystem and writes core.ignorecase = true and core.precomposeunicode = true. With precomposeunicode git normalises names read from the worktree to NFC, so the tree entry is 'caf\303\251.txt' (bytes 63 61 66 c3 a9 ...) regardless of how macOS reports the name.
Actual
grit init writes neither key (.git/config has only repositoryformatversion, filemode, bare, logallrefupdates). grit add stores the name exactly as readdir returns it: bytes 63 61 66 65 cc 81 2e 74 78 74 (NFD, 'cafe' + combining acute). The commit therefore contains a path that differs from the NFC path every Linux/Windows collaborator and every git-on-macOS user produces: the same file can end up as two different index entries / duplicate paths after merge or on checkout elsewhere (APFS hides this locally because it is normalization-insensitive). Because ignorecase is also not set, the case-collision situation on a case-insensitive APFS volume is not detected either (cloning a repo that has both README and readme silently leaves one file, with no warning; git prints a colliding-paths warning).
Environment
macOS 15.7 (24G214) arm64, Apple M3; grit 0.5.0 (curl install) and main b4bb866f5; git 2.52.0 (Homebrew); default APFS (case-insensitive, normalization-insensitive).
Found by automated dogfooding (task #138).
- Dominant language
- Rust
- Stars
- 572
- Forks
- 46
- Avg merge
- 21h 39m
- Merged PRs (30d)
- 10
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from gitbutlerapp/grit
-
area:show area:show---markdown-and-other---ma bug factory:dogfood factory:triaged persona:scripter platform:linux-cloud priority:p2 type:bug type:security
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
gitbutlerapp/grit#2303 · 1 comment ·
Maintainers usually reply within 1 day
-
area:clone area:clone-output---json---markdown bug factory:dogfood factory:triaged persona:scripter platform:linux-cloud priority:p1 type:bug type:security
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
gitbutlerapp/grit#2302 · 1 comment ·
Maintainers usually reply within 1 day
-
area:refs area:refs-store-refstore-for-each-r bug factory:dogfood factory:triaged good first issue persona:backend-author platform:linux-cloud priority:p3 type:api type:bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
gitbutlerapp/grit#2185 · 1 comment ·
Maintainers usually reply within 1 day
-
area:grit-lib-hooks-run-hook-grit-s area:hooks area:receive-pack area:transport bug factory:dogfood factory:triaged persona:server-builder platform:linux-cloud priority:p1 type:bug type:security
Difficulty 4/5 3-5 days Newbie friendliness 35/100
gitbutlerapp/grit#2457 · 1 comment ·
Maintainers usually reply within 1 day
-
grit serve dies with SIGPIPE when a receive hook exits without reading its stdin on a large pushOpenarea:grit-serve-receive-pack-hooks area:hooks area:serve bug factory:dogfood factory:triaged persona:server-builder platform:linux-cloud priority:p0 type:bug type:security
Difficulty 4/5 3-5 days Newbie friendliness 30/100
gitbutlerapp/grit#2456 · 1 comment ·
Maintainers usually reply within 1 day
All issues in gitbutlerapp/grit
Similar issues
-
Difficulty 1/5 1-3 hours Newbie friendliness 70/100
OpenZeppelin/openzeppelin-relayer#967 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
src/runs.rs:1987: a missing --source-run-id now answers 400 "Source run ... does not exist", not 404Opennightly-audit
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
antithesishq/snouty#602 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
libnativeapi/nativeapi#21 ·