Git Worktree Architecture
Sidequest uses git worktrees to let you run multiple Claude Code sessions against the same repository in parallel — each on its own branch, with its own working directory, without any stashing or switching.
What Are Git Worktrees?
Section titled “What Are Git Worktrees?”A git worktree is a linked copy of your repository that shares the same .git object store but has its own working tree and checked-out branch. Unlike cloning, worktrees share history, refs, and objects with the original repo. This means they are created instantly and use almost no extra disk space.
# Standard git: one repo, one branch at a time~/my-project (main)
# With worktrees: one repo, multiple branches simultaneously~/my-project (main) # your original repo~/.sidequest/worktrees/<quest-id> (feat/auth) # worktree for quest A~/.sidequest/worktrees/<quest-id> (fix/bug) # worktree for quest BWhy Sidequest Uses Worktrees
Section titled “Why Sidequest Uses Worktrees”Without worktrees, running parallel branches requires either cloning the repo multiple times (slow, wastes disk) or constantly stashing and switching branches (error-prone, blocks other work). Worktrees solve both problems:
- True isolation. Each quest gets its own directory. Claude Code sessions cannot interfere with each other.
- No stashing. Your main branch stays untouched. Uncommitted work in one quest does not affect another.
- Shared git history. All worktrees share the same object database. Fetches and commits in one are visible from another.
- Fast creation. Creating a worktree takes milliseconds since it only needs to check out files, not copy the entire repo.
Directory Structure
Section titled “Directory Structure”All worktrees live under a centralized directory in your home folder:
~/.sidequest/ worktrees/ <quest-id>/ # One directory per Changes quest .git # File (not directory) pointing to parent repo src/ # Full working tree for this branch ... multirepo/ <quest-id>/ # Multi-repo quests group child worktrees frontend/ # Worktree for frontend repo backend/ # Worktree for backend repo ...Each quest is identified by a UUID. The worktree path is deterministic: ~/.sidequest/worktrees/<quest-id>. This makes cleanup reliable — Sidequest can always find and remove a quest’s worktree by ID.
Branch Naming
Section titled “Branch Naming”When you create a Changes quest, Sidequest generates a branch name using Claude. The prompt and quest title are sent to Claude Code, which returns a conventional branch name like feat/add-user-auth or fix/login-validation.
The branch name is sanitized to be a valid git ref:
- Lowercased, whitespace replaced with hyphens
- Only alphanumeric characters, hyphens, dots, and slashes are kept
- Consecutive dots/hyphens collapsed, trailing dots and
.lockremoved - Truncated to 60 characters
If Claude is unavailable, Sidequest falls back to a random three-word name from the system dictionary (e.g., maple-frost-ocean).
A temporary branch quest/<first-8-chars-of-id> is created immediately so the worktree can be set up without waiting for the Claude API call. Once the real branch name is generated, the branch is renamed in place.
Worktree Lifecycle
Section titled “Worktree Lifecycle”Creation
Section titled “Creation”When a Changes quest is activated:
graph TD
A[Quest activated] --> B[Compute worktree path]
B --> C{Directory exists?}
C -->|Yes| I[Reuse existing worktree]
C -->|No| D{Branch exists?}
D -->|Yes, has unique commits| E[Create worktree from branch]
D -->|Yes, stale| F[Delete branch, recreate from base]
D -->|No| G[Create new branch from base]
E --> H[Configure upstream tracking]
F --> H
G --> H
I --> H - Sidequest computes the worktree path:
~/.sidequest/worktrees/<quest-id> - If the directory already exists, it is reused as-is
- If the branch already exists with unique commits, the worktree is created from that branch
- If the branch exists but has no unique work (stale), it is deleted and recreated from the base branch
- Otherwise, a new branch is created from the base branch (or
HEADif no base is specified) - Upstream tracking is configured so
gh pr createtargets the correct base branch
git worktree add -b feat/my-feature ~/.sidequest/worktrees/<quest-id> mainDuring Development
Section titled “During Development”Claude Code runs inside the worktree directory. All file changes, commits, and git operations happen within this isolated working tree. You can view diffs, stage files, and create pull requests from Sidequest’s UI.
The worktree shares refs with the parent repo, so remote branches fetched in one worktree are available in all of them.
Cleanup
Section titled “Cleanup”When a quest is deleted, Sidequest cleans up in this order:
- Kills the tmux session (if running) and waits for it to fully terminate
- Runs
git worktree remove --forcefrom the parent repo - Falls back to deleting the directory directly if the git command fails
- Prunes stale worktree references with
git worktree prune
Finishing a Changes Quest
Section titled “Finishing a Changes Quest”When a Changes quest is complete and you want to merge the work back:
- Create a PR. Use the built-in PR creation flow or Claude to push the branch and open a pull request against the base branch.
- Squash merge. Sidequest supports squash merging the quest branch back into the target branch. This collapses all commits from the quest into a single commit on the target, keeping your main branch history clean.
Under the hood, a squash merge runs:
git checkout maingit merge --squash feat/my-featuregit commit -m "Squashed merge of feat/my-feature"After merging, delete the quest from Sidequest to clean up the worktree and branch.
Research Quests
Section titled “Research Quests”Research quests do not create worktrees or branches. They run Claude Code directly in the project’s root directory. This is appropriate for read-only exploration, code analysis, and question-answering tasks that do not need branch isolation.
Troubleshooting
Section titled “Troubleshooting””Branch is already checked out”
Section titled “”Branch is already checked out””Git prevents two worktrees from having the same branch checked out. If you see this error, another worktree (or your main repo) already has that branch active. Delete the conflicting quest or switch the main repo to a different branch.
Orphaned worktrees
Section titled “Orphaned worktrees”If Sidequest is force-quit, worktree directories may be left behind. You can view and clean up orphaned worktrees from Settings, or remove them manually:
ls ~/.sidequest/worktrees/rm -rf ~/.sidequest/worktrees/<quest-id>cd ~/your-repo && git worktree pruneWorktree shares refs with parent
Section titled “Worktree shares refs with parent”Because worktrees share the git object store, git fetch in one location updates refs everywhere. This is a feature, not a bug — it means your quest worktrees always have access to the latest remote state.