Git Worktrees

Command Code has first-class support for git worktrees - isolated checkouts of your repository that let a session work on a separate branch in a separate directory, without touching your main checkout.

There are three ways to use them, from most manual to most automatic:

  • /worktree - manage and switch worktrees from inside a session
  • --worktree / -w - launch a session directly into a worktree
  • enter_worktree / exit_worktree - let the model isolate its own work mid-session, when you ask for it

A regular session works in your checkout. That's usually what you want - but sometimes it isn't:

  • You want to try a risky refactor without disturbing your working tree
  • You want multiple sessions in parallel, each on its own branch, with no file conflicts between them
  • You want to review a PR in a real checkout while your own branch stays untouched
  • You want the agent to do scratch work in isolation and throw it away if it doesn't pan out

A worktree gives each of these its own directory and its own branch, backed by the same repository. Everything a session does in a worktree - file edits, shell commands, test runs - happens there, and your main checkout never changes.

Command Code keeps its worktrees outside your repository:

~/code/my-app/ ← your checkout .git/ one repository, src/ untouched ~/.commandcode/worktrees/ my-app-a1b2c3/ ← name + path hash spike/ ← branch worktree-spike pr-1234/ ← branch worktree-pr-1234

The <repo> folder is named after your repository plus a short hash of its path, so two repos with the same folder name never collide. Each worktree checks out a dedicated branch named worktree-<name>.

Keeping worktrees outside the repo means they can never nest inside each other, never show up in your project's file tree, and never need .gitignore entries.

By default, a fresh worktree branches from your repo's default branch on origin (Command Code fetches first, best-effort), so it starts from a clean state matching the remote. With no remote - or when the fetch fails - it falls back to your local HEAD.

You can change this with the worktree.baseRef setting in settings.json:

{ "worktree": { "baseRef": "head" } }
ValueBehavior
"fresh" (default)Branch from the remote default branch - a clean start matching origin
"head"Branch from your current local HEAD - carries unpushed commits and feature-branch state into the worktree

A worktree is a clean checkout, so untracked-but-needed files (.env, .env.local, local secrets) are absent. List them in a .worktreeinclude file at your repo root, using .gitignore syntax:

.env .env.local config/local-overrides.json

Files that match a pattern and are gitignored are copied into every new worktree. Tracked files are never duplicated - git already puts those in the worktree.

Manage worktrees from inside a session:

CommandDescription
/worktreeList worktrees, with the current one marked
/worktree listSame as above (ls also works)
/worktree <name>Create the worktree if needed, then switch into it
/worktree new <name>Explicit create + switch (create and add also work)
/worktree remove <name>Remove a managed worktree (rm also works)

List worktrees

# In Command Code session /worktree Worktrees: