Skip to content

pre-commit hook fails the test suite: git exports GIT_DIR into hooks, which overrides git -C in tests/test_pipeline.c #2003

Description

@metehanulusoy

What happens

CONTRIBUTING.md tells contributors to install the repo hooks (git config core.hooksPath scripts/hooks). The pre-commit hook runs the full test suite. Git exports GIT_DIR into hook environments, GIT_DIR overrides git -C, and the tests in tests/test_pipeline.c that shell out to git therefore operate on the real repository instead of their temp fixture.

The result: with the documented hook installed, git commit fails the suite every time.

Reproduction — no hook needed, one variable

$ scripts/test.sh --suites pipeline
  264 passed

$ GIT_DIR="$PWD/.git" scripts/test.sh --suites pipeline
  git_context_linked_worktree   FAIL tests/test_pipeline.c:7444: run_cmd(cmd) == 32768, expected 0 == 0
  261 passed, 3 failed

Verified on main with no local changes (3627eff), macOS 15 arm64, git 2.50.1.

Line 7444 is:

snprintf(cmd, sizeof(cmd), "git -C \"%s\" checkout -b main >%s 2>&1", repo, null_dev);
ASSERT_EQ(run_cmd(cmd), 0);

With GIT_DIR set, -C no longer selects the repository: the command runs against the real checkout, where main already exists, so git exits 128.

It is not only a failing assert — the suite writes to the real repository

While tracing this I ran the test's own worktree add line with GIT_DIR set:

$ GIT_DIR=/path/to/codebase-memory-mcp/.git \
    git -C "$TMP/repo with space" worktree add -b feat2 "$TMP/wt with space"
Preparing worktree (new branch 'feat2')
Updating files: 100% (2118/2118), done.
HEAD is now at 17786374 Merge pull request #1993 from DeusData/fix/unify-type-short-name-index

It checked out 2118 files of the actual repository into the temp path and created a branch in the contributor's clone. So a contributor who follows the documented setup gets branches and worktree registrations created in their working repo by the test suite. git worktree prune plus git branch -D cleans it up, but nothing warns them it happened.

Why it is easy to miss

canonical_root_linked_worktree guards itself and reports SKIP (platform: git worktree add unavailable (git 2.5+ required)) under the same conditions — so the environment problem is rendered as a platform capability message rather than as the env-var collision it is. git_context_linked_worktree has no such guard and fails outright.

Suggested fix

Clear the git-supplied environment at the top of the hook — or in scripts/test.sh, so the suite is immune however it is invoked:

unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_PREFIX GIT_OBJECT_DIRECTORY

Belt-and-braces alternative for the tests themselves: build the git commands as env -u GIT_DIR -u GIT_WORK_TREE git -C ..., so a stray GIT_DIR in any caller's environment can never redirect a test at the real repository. git_available() at tests/test_pipeline.c:7380 is the natural place to also assert a clean env once, rather than each site defending itself.

I am happy to open a PR for whichever of the two you prefer — the hook/test.sh unset is the one-line version, the env -u wrapper is the one that holds no matter who invokes the suite. Flagging first per CONTRIBUTING, since this touches build/CI configuration.

Environment

  • main @ 3627eff, built from source with scripts/build.sh
  • macOS 15 (Darwin 25.6.0), arm64, clang, git 2.50.1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.securitySecurity vulnerabilities, hardening

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions