SDK worktree creation contaminates parent repo's core.hooksPath config
Summary
The Claude Agent SDK's worktree creation logic writes core.hooksPath to the parent repository's .git/config without using the --worktree flag, causing the parent repo to lose access to the user's global git hooks.
Mechanism
In @anthropic-ai/claude-agent-sdk (versions 0.40.1 and 0.42.1 observed), the copyWorktreeIncludeFiles function searches for .husky or .git/hooks directories and writes their path to the worktree's config:
let Y = WN(q, ".husky"),
A = WN(q, ".git", "hooks"),
O = null;
for (let j of [Y, A]) try {
if ((await Y85(j)).isDirectory()) { O = j; break }
} catch {}
if (O) {
await M7(D7(), ["config", "core.hooksPath", O], { cwd: K });
}
Because git worktrees share .git/config with the parent repo by default (unless extensions.worktreeConfig is enabled), this command writes into the parent's config, overriding any user-configured global hooks with a path to the parent's stock .git/hooks directory.
Impact
When Claude Code creates a worktree from a parent repository:
- The parent repo's
core.hooksPathis silently overwritten with/path/to/parent/.git/hooks - User's global git hooks are disabled in the parent repo
- The path written typically contains only sample hook files, not functional hooks
- User discovers the issue only when hooks stop firing
Evidence
- SDK source locations:
@anthropic-ai/claude-agent-sdk/cli.jsfunctioncopyWorktreeIncludeFiles - Observed behavior: Five Claude Code worktrees spawned from
gmail_extensionrepo (May 11-14) correlate with observedcore.hooksPathoverride - Path written matches exactly:
hooksPath = /Users/janac/Documents/GitHub/gmail_extension/.git/hooks - Verified git pull/fetch/merge do NOT restore the override (ruled out as alternative cause)
Suggested Fix
- Before creating worktrees, enable
extensions.worktreeConfig=trueon the parent repo:
``bash``
git -C <parent_repo> config extensions.worktreeConfig true
- Write
core.hooksPathwith the--worktreeflag to isolate the config to the worktree only:
``javascript``
await M7(D7(), ["config", "--worktree", "core.hooksPath", O], { cwd: K });
This ensures the hooks path applies only to the worktree and doesn't contaminate the parent repo's shared config.
Reproduction
- Configure global git hooks via
git config --global core.hooksPath <path> - Create a Claude Code worktree from any parent repo
- Check the parent repo's config:
git -C <parent_repo> config core.hooksPath - Observe the global hooks path has been replaced with
<parent_repo>/.git/hooks
Environment
- Claude Code versions with SDK 0.40.1 and 0.42.1
- macOS (likely affects all platforms)
- Git 2.x with standard worktree configuration
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗