fix(core): scrub GIT_* env when spawning git so git hooks can't corrupt the repo#149
Merged
Conversation
…pt the repo git resolves the repository from GIT_DIR / GIT_WORK_TREE / GIT_INDEX_FILE in the environment before the directory it runs in. When the test suite runs inside a contributor's pre-commit hook, git exports those vars and they leak into the test subprocesses: `git init` in a temp repo then targets the real repo's git dir with no work tree and re-initializes it as bare (core.bare=true), breaking every worktree. snapshots.ts's production git() helper had the same exposure. Add a shared gitSpawnEnv() helper (extracted from worktree/index.ts's existing inline scrub) that strips GIT_* from the env, and use it in snapshots.ts, in worktree/index.ts (dedupe), and in the snapshots/worktree test setups. Export it from @deepcode/core for reuse by other git-spawning code. Validated by running the snapshots + worktree-tools suites with GIT_DIR and GIT_INDEX_FILE set to bogus paths (simulating the hook): all green and core.bare stays false. Adds a gitSpawnEnv unit test. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
6 tasks
oratis
added a commit
that referenced
this pull request
Jun 3, 2026
… Claude parity) (#150) Codex and Claude Code both expose /diff and /release-notes; Claude also has /bug (/feedback). DeepCode had none of them. - /diff: `git status --short` + `git diff HEAD` (truncated to 300 lines) + untracked files, in the session cwd. Clean message outside a git repo. - /release-notes: prints the latest CHANGELOG.md section (walks up from cwd). - /bug (alias /feedback): prints a prefilled github.com/oratis/deepcode issue link, carrying the current model/mode/effort in the body. git is spawned with GIT_* stripped from the env (inlined to keep this PR independent of #149) so a leaked GIT_DIR can't redirect it. Adds 6 tests. Co-authored-by: t <t@t> Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
git resolves the repository from
GIT_DIR/GIT_WORK_TREE/GIT_INDEX_FILEin the environment before the directory it runs in. When the suite runs inside a contributor's pre-commit hook (husky →pnpm test), git exports those vars and they leak into the test subprocesses —git initin a test's temp repo then targets the real repo's git dir with no work tree and re-initializes it as bare (core.bare=true), breaking every worktree (fatal: this operation must be run in a work tree).snapshots.ts's productiongit()helper had the same exposure.This extracts the GIT_*-stripping that
worktree/index.tsalready did inline into a sharedgitSpawnEnv()helper and uses it insnapshots.ts,worktree/index.ts(dedupe), and the snapshots/worktree test setups. Exported from@deepcode/core.Test plan
pnpm typechecksnapshots+worktree-tools+ newgit-envsuites withGIT_DIR/GIT_INDEX_FILEset to bogus paths (simulating the hook) → 15 passing, andcore.barestayedfalse(repo not corrupted). Before this change that run failed and corrupted the repo.prettier --check+eslintcleanAdds
git-env.test.ts(unit) covering the strip/preserve/no-mutate behavior.Documentation
// why:comment ingit-env.tsexplains the hazard.Release notes label
release-notes:fixRelated
Discovered while opening PRs during a Codex/Claude Code/DeepCode alignment review — the pre-commit hook corrupted this worktree (
core.bare=true) the first time the suite ran inside a commit.