macOS: grit init omits core.precomposeunicode/ignorecase; grit add stores NFD (decomposed) paths in the index and trees

Closed
#910 1 comment 0 reactions 0 assignees View on GitHub

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

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

area:index area:init-add-index-macos-path-hand area:init-add-index-macos-path-handling bug factory:dogfood factory:triaged priority:p1 type:bug type:compat

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from gitbutlerapp/grit

All issues in gitbutlerapp/grit

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.