BlogGit and worktrees
How do I use git worktrees with Claude Code?
Run claude --worktree <name> from your repository. Claude Code creates .claude/worktrees/<name>/ on a new branch called worktree-<name>, starts the session inside it, and offers to clean it up when you exit. Run the same command with another name in a second terminal and you have two agents that can't edit each other's files.
What a worktree is
A git worktree is a separate working directory with its own files and branch, attached to the same repository. All worktrees share history and remotes, but each has its own checkout. For parallel agents, that means each session edits its own copy of the code.
Without Kanbell: step by step
1. Accept workspace trust once
Interactive --worktree runs need workspace trust. If you have never run Claude in this repository, run claude once and accept the dialog. Otherwise --worktree exits with an error.
2. Ignore the worktrees folder
echo ".claude/worktrees/" >> .gitignore
Without this, the worktree contents show up as untracked files in your main checkout.
3. Copy your local files in
Create .worktreeinclude at the repository root. It uses .gitignore syntax, and only files that match and are gitignored get copied:
.env
.env.local
config/secrets.json
This applies to --worktree sessions, subagent worktrees and parallel sessions in the desktop app.
4. Start the sessions
claude -w feature-auth
claude -w fix-1234
claude -w # Claude picks a name, such as bright-running-fox
Then install dependencies in each worktree, or ask Claude to. A worktree is a fresh checkout, so node_modules or a virtualenv isn't there yet.
To start from a pull request:
claude --worktree "#1234"
Quote it so the shell doesn't treat # as a comment. Claude Code fetches the PR head from origin into .claude/worktrees/pr-1234. GitLab merge request URLs work too (v2.1.233 or later).
To get a tmux session for the worktree:
claude -w feature-auth --tmux
It uses iTerm2 native panes when available; --tmux=classic forces plain tmux.
5. Choose the base branch
By default, new worktrees branch from the remote's default branch ("fresh"). To branch from your current local work, set this in settings:
{
"worktree": {
"baseRef": "head"
}
}
baseRef accepts only "fresh" or "head", not a branch name. For a specific existing branch, use git directly (step 7).
6. Exit and clean up
When you exit, Claude Code checks the worktree:
- Clean, unnamed session: worktree and branch are removed.
- Clean, named session: it asks first.
- Changes, untracked files or new commits: it asks whether to keep or remove. Keep it, and it prints a
claude --worktree <name> --resumecommand to come back.
Runs with -p have no exit prompt and aren't cleaned up. Remove those with git worktree remove, after git worktree unlock if git says it's locked.
7. Or manage worktrees with git
git worktree add ../myapp-feature-a -b feature-a # new branch
git worktree add ../myapp-bugfix fix-issue-456 # existing branch
cd ../myapp-feature-a && claude
git worktree list
git worktree remove ../myapp-feature-a
git worktree remove refuses to remove a worktree with uncommitted changes unless you pass --force.
What worktrees still share
- The
.gitdirectory. Commits from any worktree land in the same repository. - Permission approvals. "Yes, and don't ask again" in a worktree session saves the rule to the main checkout's
.claude/settings.local.json(v2.1.211 or later; on Windows the rule stays in the worktree), so it applies in every worktree. - Project plugins, and untracked skills, agents and commands from the main checkout when the worktree has none of its own.
- Anything outside the checkout: databases, ports, caches in your home folder.
Limits of this method
- Setup per worktree. Dependencies, build caches and generated files start empty in each new checkout.
- Disk use. Each worktree is a full working tree. Background-session and subagent worktrees are swept after
cleanupPeriodDaysonly when they hold no work. - Hook paths don't follow.
${CLAUDE_PROJECT_DIR}keeps pointing at the main checkout; readcwdfrom the hook input to get the worktree path. - Tracking them is on you. Which worktree holds unmerged work, and which session runs in which one, means
git worktree listplus memory.
With Kanbell
Kanbell is a macOS app (Apple Silicon) that keeps worktrees in view while you work.
- Git panel next to the terminals: changes, diffs, history and worktrees for the project, so you see what each worktree changed without
cd-ing around. - One window per project, with real terminals in panes and tabs. Run
claude -w <name>in each, as above. - Agent state: for Claude Code, working, waiting or done, and whether the wait is a question or a permission; an orange dot and ⌘⇧J to reach the agent that needs you.
Kanbell uses your git and your worktrees as they are. No account and no Kanbell server.
FAQ
Why is my .env missing in the worktree?
A worktree is a fresh checkout, so untracked and gitignored files aren't there. List them in a .worktreeinclude file at the repository root and Claude Code copies them into each worktree it creates.
Which branch does the worktree start from?
By default, the repository's default branch on the remote, usually main. Set worktree.baseRef to "head" in settings to branch from your current local HEAD instead.
How do I come back to a worktree session later?
Keep the worktree when you exit, then run the claude --worktree <name> --resume command Claude Code prints. Passing an existing name to --worktree reopens that worktree.
Can I start a worktree from a pull request?
Yes. claude --worktree "#1234" fetches that pull request's head from origin and creates .claude/worktrees/pr-1234.