Summary
.husky/pre-push reliably fails on Windows worktrees because core.autocrlf=true (the Git-for-Windows default) plus a missing repo-wide .gitattributes cause pnpm format:check to mark ~600 unrelated files dirty on every pre-push. The hook auto-fixes them with pnpm format but still exits 1 because FORMAT_EXIT was captured before the fix.
Problem
On Windows with default Git config, files arrive on disk with CRLF line endings (autocrlf converts LF → CRLF on checkout). Prettier's project config enforces LF, so pnpm format:check flags the entire tree as needing format. The hook script's design bug is that it captures FORMAT_EXIT before the auto-fix runs, so even after the fix succeeds the hook still reports failure.
Impact
Steps to reproduce (Windows + Git Bash + Git for Windows default config)
git clone https://github.com/tinyhumansai/openhuman.git.
- Make a one-line change to any TS or Rust file.
git commit -m "test" && git push -u origin <branch>.
- Pre-push hook fails:
pnpm format rewrites ~600 unrelated files; FORMAT_EXIT=1 short-circuits the hook even after auto-fix.
Environment: Windows 11, Git for Windows 2.x, core.autocrlf=true (default), no repo-wide .gitattributes.
Solution
Two changes, both small:
- Add a repo-root
.gitattributes enforcing * text=auto eol=lf plus explicit binary excludes for the file types in the tree (.png, .ico, .icns, .lottie, etc.). Git stores and checks out everything with LF regardless of core.autocrlf.
- Document
git config --local core.autocrlf false in CONTRIBUTING.md (or wherever onboarding lives) for Windows contributors, so the working-tree state matches the committed state from the start.
Separate but related: fix .husky/pre-push to capture FORMAT_EXIT after the auto-fix succeeds, so the hook actually self-heals instead of always exiting 1 when format check trips. Same for LINT_EXIT.
Acceptance criteria
Related
Summary
.husky/pre-pushreliably fails on Windows worktrees becausecore.autocrlf=true(the Git-for-Windows default) plus a missing repo-wide.gitattributescausepnpm format:checkto mark ~600 unrelated files dirty on every pre-push. The hook auto-fixes them withpnpm formatbut still exits 1 becauseFORMAT_EXITwas captured before the fix.Problem
On Windows with default Git config, files arrive on disk with CRLF line endings (autocrlf converts LF → CRLF on checkout). Prettier's project config enforces LF, so
pnpm format:checkflags the entire tree as needing format. The hook script's design bug is that it capturesFORMAT_EXITbefore the auto-fix runs, so even after the fix succeeds the hook still reports failure.Impact
git push --no-verify, which masks other potential signal (lint / typecheck / cargo check) until CI runs.git statusand risks accidental commits of unrelated reformatting.Steps to reproduce (Windows + Git Bash + Git for Windows default config)
git clone https://github.com/tinyhumansai/openhuman.git.git commit -m "test" && git push -u origin <branch>.pnpm formatrewrites ~600 unrelated files;FORMAT_EXIT=1short-circuits the hook even after auto-fix.Environment: Windows 11, Git for Windows 2.x,
core.autocrlf=true(default), no repo-wide.gitattributes.Solution
Two changes, both small:
.gitattributesenforcing* text=auto eol=lfplus explicit binary excludes for the file types in the tree (.png,.ico,.icns,.lottie, etc.). Git stores and checks out everything with LF regardless ofcore.autocrlf.git config --local core.autocrlf falseinCONTRIBUTING.md(or wherever onboarding lives) for Windows contributors, so the working-tree state matches the committed state from the start.Separate but related: fix
.husky/pre-pushto captureFORMAT_EXITafter the auto-fix succeeds, so the hook actually self-heals instead of always exiting 1 when format check trips. Same forLINT_EXIT.Acceptance criteria
git statusshow hundreds of unrelated files modified afterpnpm format.format:checkfails,pnpm formatauto-fixes, and the hook exits 0 with the auto-fix staged (or surfaces a clear "stage and re-push" instruction)..gitattributescovers the file extensions actually used in the tree (binary/text classification), and a comment documents the policy..github/workflows/coverage.yml).Related
## Impact.