A git hook run from a linked worktree hands its children GIT_DIR as a full path, so a test's git init re-creates the real repository
Fact
git exports GIT_DIR (and GIT_INDEX_FILE and friends) to the hooks it runs, and a hook passes them to everything it starts. Pushed from a linked worktree, GIT_DIR is the full path of that worktree's own git folder (.git/worktrees/<name>), so it wins over the folder a child git command runs in. A test that makes a scratch repository with git init in a temporary folder re-initialises the real one instead — with GIT_DIR set and no work tree, as bare — and its git config user.email … lands in the shared .git/config. The same hook pushed from the main checkout did no harm.
Why it matters
core.bare = true in the shared config breaks every checkout of the repository at once ("fatal: this operation must be run in a work tree"), including other people's and other agents' worktrees, and the test identity it wrote becomes the author of every later commit there. The hook just reports a few failing tests.
How to apply
- A hook that runs tests or tools strips the variables first:
Object.fromEntries(Object.entries(process.env).filter(([k]) => !k.startsWith('GIT_'))), orenv -u GIT_DIR -u GIT_WORK_TREE -u GIT_INDEX_FILE …in shell. - Test helpers that create repositories clear
GIT_DIRin the environment they pass to git;git -C <dir>alone does not override it. - Repair:
git config --file <repo>/.git/config core.bare false, and unset anyuser.*a test wrote there.