Skip to content

Commit bd6662e

Browse files
ngallodevclaude
andcommitted
fix(hooks): run pre-commit audit and tests without git's hook environment
Git exports GIT_DIR, GIT_INDEX_FILE and related repo-local variables to hooks. When a commit is made from a linked worktree, GIT_DIR points at the worktree's gitdir. The pre-commit hook then runs `make test`, and test fixtures that call `git -C <tmpdir> init/add/commit/config` inherit those variables. Their commands act on the repository being committed to instead of the fixture repo: - fixture commits ("init", "artifact", "head-only change") land on the branch checked out in the worktree, sweeping up whatever is staged; - fixture `git config` writes user.name/user.email and core.bare=true into the shared .git/config, which breaks the main checkout; - a fixture `git commit` runs this same hook again, recursing. This happened in practice on 2026-09-29 while committing review fixes from agent-workflow worktrees: several local branches picked up fixture commits and .git/config gained core.bare=true plus a fixture identity. Unset `git rev-parse --local-env-vars` after the formatting and lint steps (which need GIT_INDEX_FILE to see the staged index) and before the security audit and test run. Verified with a throwaway repo plus linked worktree whose pre-commit hook runs a fixture-style `git -C <tmp>` init/commit/config: without the unset, the fixture commit replaced the worktree commit and the shared config got [email protected]; with it, the real commit landed, the shared config was unchanged and the fixture got its own repository. Committed with --no-verify because the hook being fixed is the thing under test. Co-Authored-By: Claude Opus 5.5 <[email protected]>
1 parent 72faa8c commit bd6662e

1 file changed

Lines changed: 7 additions & 0 deletions

File tree

‎scripts/hooks/pre-commit‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ echo "pre-commit: running all linters in parallel..."
3737
# has clang-tidy on PATH. `make lint-tidy` remains available for a full audit.
3838
make -j3 -f Makefile.cbm lint-ci lint-tidy-diff CLANG_FORMAT="$FORMATTER"
3939

40+
# Git exports GIT_DIR, GIT_INDEX_FILE and related variables to hooks. Test
41+
# fixtures run `git -C <tmpdir> init/commit/config`; with those variables set,
42+
# the commands act on this repository instead of the fixture repo (moving the
43+
# current branch, writing user.* and core.bare into .git/config). Drop them for
44+
# the audit and the test run. The formatting and lint steps above need them.
45+
unset $(git rev-parse --local-env-vars)
46+
4047
echo "pre-commit: security audit (source-level)..."
4148
scripts/security-audit.sh
4249

0 commit comments

Comments
 (0)