# Git worktrees

URL: https://docs.orchestrator.inc/plugins/workspaces/worktree/

> Isolated branches and files for sessions in Git projects.

Each Git-backed session gets its own worktree and branch, based on the repository's default branch rather than the branch currently checked out in your source repository. Multi-repository workspaces resolve the root and each child repository independently.

```bash
ao project add --path /path/to/repo --worker-agent codex
ao spawn --project my-repo --name fix-auth
```

Worktrees keep checked-out files separate while sharing the repository's Git object database.

<span id="how-ao-chooses-the-base-branch" />

## How Orchestrator chooses the base branch

Orchestrator asks the selected remote for its default branch. If it cannot reach the remote, Orchestrator uses that remote's cached `HEAD`. If the remote has no default branch, a fetched branch named in the spawn request can seed the explicitly requested session branch.

Orchestrator records the base ref for each repository. Workspace and review diffs use it to recalculate the merge base after a rebase or when the repository default advances, so upstream-only changes do not appear as agent edits.

## Typed project settings

The daemon stores project configuration as validated JSON in SQLite. Relevant fields include:

| Field                                        | Purpose                                                                               |
| -------------------------------------------- | ------------------------------------------------------------------------------------- |
| `defaultBranch`                              | Base branch for new session worktrees; `auto` resolves each repository's Git default. |
| `env`                                        | Extra environment variables passed to agent runtimes.                                 |
| `symlinks`                                   | Repository-relative paths linked into each workspace.                                 |
| `postCreate`                                 | Commands run after workspace creation.                                                |
| `agentRules`, `agentRulesFile`               | Standing worker instructions.                                                         |
| `orchestratorRules`, `orchestratorRulesFile` | Standing orchestrator instructions.                                                   |

Use `ao project set-config <id> --help` for flags. To pass the complete object with `--config-json`, first read the [full-config warning](/configuration/projects#update-from-the-cli).

## Cleanup safety

`ao session kill` terminates the runtime, but preserves a worktree when cleanup cannot safely remove it. `ao session cleanup` reclaims eligible terminated workspaces and skips dirty ones; run with `--dry-run` first when you want to inspect the candidates. Each result is recorded, so a workspace already released is not offered again, and a skipped one is reported with its reason (uncommitted changes, a missing repository, or a worktree locked with `git worktree lock`) and a stable code such as `dirty`, `missing_repo`, `locked_worktree` or `permission_error`, which scripts can match in the `ao session cleanup` output or the `/api/v1/sessions/cleanup` response.

Only archiving a session (`ao session kill`, including the archive after a merged PR) and `ao session cleanup` remove worktrees. An agent that exits on its own keeps its worktree. In the background, AO only finishes a cleanup that was already accepted but interrupted (for example by a daemon restart) and, for sessions whose worktree folder is already gone, prunes git's leftover registration and records the release; it never removes a worktree that is still on disk. A stale lock that `git worktree add` left behind is lifted during cleanup; any other lock is kept and reported.

After cleanup, `ao session delete <id>` permanently removes the session record and its AO history; with `--cleanup` it cleans the worktree up first, never forced. Its session ID is never reused, and its spend stays in the agent account usage totals. In the desktop app, the trash icon on an archived session card does the same, cleaning up first.

To delete archived sessions automatically, choose a period under Settings → Sessions → **Delete archived sessions** (7, 30 or 90 days; Never by default). Only sessions whose worktree is already cleaned up are deleted: retention never removes a worktree, so a dirty or kept one keeps its session.
