[BUG] `--worktree` fails in non-git repos even when `WorktreeCreate` hook is configured
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
claude --worktree <name> immediately exits with an error in non-git repositories (e.g., Mercurial/Sapling), even when a WorktreeCreate hook is configured in ~/.claude/settings.json. The git repository check in the setup function runs before the hook is considered, so the hook never fires.
What Should Happen?
When a WorktreeCreate hook is registered, claude --worktree should delegate to that hook instead of requiring a git repository. The hook mechanism exists precisely to support non-git VCS systems (Mercurial, Sapling, SVN, etc.), and the internal worktree creation function already handles this correctly — it just never gets called.
Error Messages/Logs
Error: Can only use --worktree in a git repository, but /path/to/repo is not a git repository
Steps to Reproduce
- Navigate to a non-git repository (e.g., a Mercurial/Sapling repo)
- Add a
WorktreeCreatehook to~/.claude/settings.json:
``json``
{
"hooks": {
"WorktreeCreate": [
{
"type": "command",
"command": "my-worktree-create-script $name"
}
]
}
}
- Run
claude --worktree mytree - Error fires immediately — the hook is never invoked
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
v2.1.58
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Root cause in code:
The setup function checks isGitRepo() before the worktree creation function is called. The worktree creation function itself already correctly checks for a WorktreeCreate hook first, but the early guard prevents it from ever being reached:
setup() {
if (worktreeFlag) {
if (!isGitRepo()) // ← blocks non-git repos before hooks are checked
exit("not a git repo")
// ... git-specific setup ...
createWorktree() // ← never reached for non-git repos
}
}
createWorktree() {
if (hasWorktreeCreateHook()) { // ← correctly checks for hook first
delegateToHook(name) // but never gets called
} else {
// git-based worktree
}
}
Suggested fix: Check for a WorktreeCreate hook before the git repo check. If a hook exists, skip git-specific pre-checks and delegate directly:
if (worktreeFlag) {
if (hasWorktreeCreateHook()) {
// Hook-based path: skip git checks entirely
let result = await createWorktree(sessionId, name);
process.chdir(result.worktreePath);
} else {
// Existing git-based path (unchanged)
if (!isGitRepo()) exit("not a git repo");
// ...
}
}
This is consistent with how agent worktree creation and the worktree creation function itself already handle the hook-based path.
Related: #27439 — --worktree also fails in bare git repos due to the same early guard. Both issues stem from the overly restrictive git check in the setup function.
Environment:
- OS: macOS / Linux
- VCS: Sapling (Mercurial-based)
4 Comments
I have the same issue, does this hook work at all for non-git repo? claude code suggested to use EnterWorktree instead of this.
Workaround: a
PreToolUsehook can initialize git before the worktree is created:This ensures
--worktreeworks even in directories that weren't initially git repositories.This was fixed in v2.1.85 —
--worktreenow defers to a configured WorktreeCreate hook in non-git directories instead of failing immediately. If you're still seeing this in the latest version, please comment with your version and repro and we'll reopen.This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.