install-lefthook postinstall fails on macOS when the repo path contains non-ASCII characters (NFC/NFD mismatch) #4272
Replies: 2 comments
|
Thanks for the detailed report — the diagnosis is exactly right, and I verified it against the installer at HEAD Confirmed from source: no Unicode normalization anywhere. // scripts/install-lefthook.mjs:569-572
function normalizedPath(path) {
const normalized = resolve(path)
return process.platform === 'win32' ? normalized.toLowerCase() : normalized
}
Error 1 — Error 2 — The layer worth adding: the direct comparisons of path-valued config. Once a worktree
Suggested shape: keep Your workaround observation ( Thanks again for the precise trace; this one is very reproducible to reason about. |
|
I implemented and verified a reference fix for this report:
The installer now routes config-origin, The deterministic cross-platform regression first reproduced the reported merge-driver-origin failure by modeling NFC Git config output against an NFD checkout path. The fixed suite covers first install, repeat install, marker-backed relocation, exact rollback after a later Lefthook failure, non-macOS separation, and relative-path refusal. Validation passed: focused 5/5; full installer suite 37 passed with 6 platform skips; typecheck, lint, translation pairing, doc-sync 28/28, diff integrity, pre-commit, and the pre-push host build/typecheck. |
Uh oh!
There was an error while loading. Please reload this page.
Environment: macOS (Darwin 25.6), Apple Git 2.50.1 (
core.precomposeunicodedefaulting to true), Node 22, repository cloned under a path containing non-ASCII characters (e.g.…/Ai İçerikler/deepseek-harness).Symptom:
pnpm installfails at the root postinstall:With that first comparison patched, the next check fails the same way:
Cause: a Unicode-normalization (NFC/NFD) mismatch in
scripts/install-lefthook.mjspath and value comparisons.git rev-parse --show-toplevel/--absolute-git-diryield NFD strings, and every path the script derives from them (worktreeConfigPath,hooksPath) is NFD.core.precomposeunicode=true(the macOS default), git precomposes command-line arguments and prints--show-originpaths in NFC. So the origin path read back fromgit config --show-originis NFC, and a path value stored viagit config --worktree core.hooksPath <NFD path>reads back as NFC.normalizedPath()compares byte-for-byte (resolve(path)only), and the hooksPath verification comparesinstalledEntry.value !== hooksPathdirectly, so both verifications fail on any repository path containing characters affected by normalization (İ, ç, ü, é, ä, CJK with combining marks, …). The installer then rolls back and postinstall exits 1.Reproduction: on macOS,
git clonethe repository into a directory whose path contains e.g.İçerikler, thenpnpm install.Local workaround that made install pass:
.normalize('NFC')added to both sides of the comparison innormalizedPath(), andgit config core.precomposeunicode falsein the clone (so values git stores and reports stay in the same NFD form the filesystem produces).Suggested fix: apply NFC normalization consistently in the installer — in
normalizedPath()and in every comparison of path-valued config (core.hooksPath, the ownership-marker checks) — rather than relying on git and Node agreeing on a normalization form. That removes the dependency on thecore.precomposeunicodesetting entirely.Happy to provide more diagnostics if useful.
🤖 Diagnosed with Claude Code
All reactions