[Feature Request] Configurable worktree directory location with sibling directory support

Status Open
Reported on v2.1.50
Maintainer reply None cached
Activity 11 comments · opened Feb 21, 2026

Bug Description
Please provide a way to configure where worktrees go, specifically a sibling directory. I asked Claude what is the recommended location for worktrees, and it said: "The widely recommended convention is to put worktrees in a sibling directory to the main repository, not inside it." Using a subdirectory like you do now causes problems.

Environment Info

  • Platform: darwin
  • Terminal: iTerm.app
  • Version: 2.1.50
  • Feedback ID: f0086445-61db-4342-b4ea-df9fff886599

Errors

[]

View original on GitHub ↗

11 Comments

ChiragThesia · 6 months ago

Yup, plus one to this! If you are using webpack, then it will go through the node_modules in the worktree and take ages, or sometimes stall.

Being able to choose the directory where the tree is built would be awesome!

Now I know I can use the hooks, but then some of the nice things don't come in that come with workt ree management by --worktree

aparajita · 6 months ago

@ChiragThesia for now you can achieve this with a hook.

https://code.claude.com/docs/en/hooks#worktreecreate

Or you can use a claude code/worktree script I wrote: https://github.com/aparajita/claude-code/tree/main/commands/worktree

ChiragThesia · 6 months ago
https://github.com/aparajita/claude-code/tree/main/commands/worktree

@aparajita yup, I actually tried the hooks first, but I liked the auto cleanup and all.

Or you can use a Claude code/worktree script I wrote: https://github.com/aparajita/claude-code/tree/main/commands/worktree

Haha, same, I did the same and built a script. Thank you for sharing this. I can improve mine by comparing with yours. Thank you!

coreh · 5 months ago

This would also solve monorepo workspace symlink resolution issues — worktrees inside the repo share node_modules which points back to the main checkout's packages/, breaking module resolution. Related: #27744

turadg · 5 months ago

Claude 1.1.7714 (3bd6f6) 2026-03-19T14:50:53.000Z still defaults to within-repo which breaks tooling.

<img width="749" height="86" alt="Image" src="https://github.com/user-attachments/assets/f5dcfe4e-1e1d-44a1-a95d-fca220b65b83" />

Please consider making sibling directory the default. https://github.com/max-sixty/worktrunk puts them at $repopath.$branchname which works well.

aparajita · 5 months ago

@turadg Thanks for the worktrunk link. I create my own worktree script which does much the same thing, but will check out worktrunk.

yurukusa · 5 months ago

A PreToolUse hook on EnterWorktree can redirect worktree creation to a sibling directory:

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
[ -z "$COMMAND" ] && exit 0
if echo "$COMMAND" | grep -qE 'git\s+worktree\s+add'; then
    TARGET=$(echo "$COMMAND" | grep -oE 'worktree\s+add\s+\S+' | awk '{print $3}')
    if [ -n "$TARGET" ]; then
        GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
        if [[ "$TARGET" == "$GIT_ROOT"* ]]; then
            BASENAME=$(basename "$TARGET")
            SIBLING="$GIT_ROOT/../worktrees/$BASENAME"
            echo '{"hookSpecificOutput":{"additionalContext":"Worktree location override: Use '"$SIBLING"' instead of '"$TARGET"' (sibling directory, not inside repo)."}}'
        fi
    fi
fi
exit 0

Create .claude/worktree-config:

WORKTREE_BASE=../worktrees
CONFIG=".claude/worktree-config"
if [ -f "$CONFIG" ]; then
    source "$CONFIG"
    echo '{"hookSpecificOutput":{"additionalContext":"Worktree config: Create worktrees in '"$WORKTREE_BASE"' (sibling directory)"}}'
fi
exit 0
{
  "hooks": {
    "PreToolUse": [{"matcher": "Bash", "hooks": [{"type": "command", "command": "bash ~/.claude/hooks/worktree-location.sh"}]}],
    "Notification": [{"matcher": "start", "hooks": [{"type": "command", "command": "bash ~/.claude/hooks/worktree-config.sh"}]}]
  }
}

The hook detects git worktree add targeting a path inside the repo and redirects it to a sibling directory.

aparajita · 5 months ago

@yurukusa Does the PreToolUse hook allow user interaction? If not, it's a blocker for me.

Qythyx · 1 month ago

+1 — and a concrete tooling breakage I don't see called out yet: because Claude Code creates worktrees under .claude/worktrees/, and that path is (per the docs' own recommendation) added to .gitignore, any tool that respects .gitignore skips files inside the worktree. In our case CSharpier and other linters/formatters silently skip the worktree's source, so formatting/lint simply don't run there — which undercuts the whole point of working in the worktree.

Current workarounds are a WorktreeCreate hook, or worktree.bgIsolation: "none" + manual git worktree add ../worktrees/<name> — both more setup than this should need. A worktree.baseDirectory / worktree.location setting to point worktrees at a sibling directory outside the repo (as this issue requests) would fix it cleanly and keep worktrees out of .gitignore's way.

(Posting here after #28242 was closed as a duplicate of this and locked.)

lukstafi · 1 month ago

The custom path support is broken under Windows-driven WSL sessions. Clicking Custom opens a file picker, this generates a Windows-style path, and then that path is ignored and the worktree is created nested under the repository (as per default).

Edited to add: I'm fixing my build system to work with nested directories, so the fix to this is won't be needed for me anymore.

bobbypierce42 · 29 days ago

+1 - Here's failure mode plus a concrete proposal.

The hook path isn't a _real_ _workaround_. It worked in one repo and not in another, and I'm still tracking down why (likely a conflict on my end, and I'll find it). But...that's rather the point. A hook is imperative, so it has to win against whatever else is loaded in that repo. A setting is declarative, so there's nothing for it to lose to. One of those I debug on a Friday night; the other just...works.

Like many developers, I work across dozens of repos and a few monorepos under an enforced directory taxonomy, and a lot of tooling keys off those paths: backup exclusions, local indexing, ignore-file scope, and scripts that discover repos by location. A worktree that lands outside that tree is invisible to all of it, and relocating it after creation defeats the purpose.

Similarly - having two different harnesses working in one repository is commonplace - but having significantly differing worktree management complicates that delicate orchestration further.

The ask:

{ "worktreeDirectory": ".worktrees" }

Resolve relative values against the repo root, so the above yields /path/to/repo/.worktrees/<branch>. Absolute paths and ~ keep working for anyone who wants a central store, so one setting covers both camps.

I'd argue for repo-relative as the default because the value is portable. No machine-specific path means it can be committed to a shared settings file and resolve correctly for every developer on the team (an absolute default can never do that).

One objection I'd expect: a worktree nested inside the working tree shows up as untracked content. Writing .worktrees/ to .git/info/exclude at creation handles that without touching anyone's .gitignore.

Unset falls back to current behavior, so nothing breaks. Happy to test a prerelease against my setup if that's useful.