cd /news/developer-tools/our-git-hook-tests-escaped-their-tem… · home topics developer-tools article
[ARTICLE · art-126513] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

our git hook tests escaped their temporary repositories

A maintainer of the Nobulex project found that its pre-push Git hook tests were escaping their temporary repositories and mutating the calling repository's metadata, after Git exported GIT_DIR into the hook environment and the test subprocess inherited it. The fix uses `git rev-parse --local-env-vars` to strip repository-local environment variables from the selftest process before fixture commands run, preserving the parent hook's context. The maintainer notes the initial run affected the worktree branch, index, and shared core.bare setting, all of which were restored, and no fixture commits were pushed publicly.

by read1 min views2 publishedSep 11, 2026

our pre-push check failed 13 tests. the bigger problem was that some of those tests had changed the repository they were supposed to protect.

this happened in Nobulex, the project i maintain. the investigation, fix and this write-up used AI assistance.

the tests create temporary Git repositories and run fixture commands inside them. we treated the subprocess working directory as the boundary. that assumption broke when the suite ran from a Git hook in an isolated worktree.

Git had exported GIT_DIR into the hook's environment. the test process inherited it. changing cwd to a temporary directory did not override the repository Git had already been told to use. fixture commands reached the calling repository's metadata instead.

the initial run affected our worktree branch and index, plus the shared core.bare setting. those were restored. no fixture commits were pushed publicly.

Git's hook documentation describes this exact boundary: hooks inherit repository-local environment variables, and commands aimed at another repository or worktree should clear them.

the fix asks Git for that list with git rev-parse --local-env-vars, then removes those names from the selftest process environment before fixture imports or commands run. clearing them there preserves the parent hook's context for its own repository checks.

we then compared the old and fixed versions in disposable clones using the inherited hook environment:

HEAD changed.

the full pre-push guard also passed. the patch is here. the useful check was the state comparison. a passing test count would not, by itself, tell us whether the caller had been left untouched. for tests that create repositories, the inherited environment belongs in the isolation check alongside the temporary directory.

── more in #developer-tools 4 stories · sorted by recency
── more on @nobulex 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/our-git-hook-tests-e…] indexed:0 read:1min 2026-09-11 ·