Worktrees

Check session worktree status, promote or prune them, and understand what the reaper cleans up automatically.

Goal#

Each dispatched session gets its own git worktree on branch orch/<session> under paths.worktrees, isolated from the project's main checkout. Learn how to inspect, promote, and clean these up — and what orch already does for you in the background.

Steps#

  1. List every orch session worktree for a project:

    orch worktree status [--project <path>] [--json]
    

    Shows each worktree's branch and path, flagged dirty (uncommitted changes) or orphan (directory with no matching git worktree record). --project defaults to the registered dispatch project or the workspace root; --base overrides the detected base branch.

  2. Check the resolved base branch promote will merge into:

    orch worktree base
    

    Defaults to ORCH_GIT_BASE env, then auto-detected main/master.

  3. Merge a session's branch into base:

    orch worktree promote <session> [--strategy merge|rebase]
    

    Fails closed on conflicts — it never leaves a half-merged tree, and it never pushes to a remote. --guard-ddl (on by default) blocks the promote if the branch's changed files trip the DDL guard (a migration without a seeder/repository companion). --event (on by default) emits a content-free orch.git.promote event when the workspace is linked.

  4. Remove orphan worktree directories and orphan orch/* branches (safe, read-only-ish cleanup — nothing with a live git worktree record is touched):

    orch worktree prune
    

    Run this before promote if you're unsure a directory is still tracked.

  5. Remove one specific session's worktree and its branch outright:

    orch worktree remove <session>
    

What the reaper does automatically#

The daemon reaps dead sessions on a clock (daemon.reap_interval_sec in orch.yaml, default 60s; 0 turns the loop off). For every session it finds abandoned, it:

  • releases any shared_locks rows that session held,
  • fails its running task row,
  • and — for an isolated (non-in-place) checkout only — removes the worktree the same way a normal finish would.

You don't need to run worktree remove or lock release yourself after a crashed or killed session; the next reap pass (or the one that runs immediately at daemon startup) does it. orch worktree prune still exists for orphan directories/branches the reaper's own bookkeeping doesn't cover (e.g. a directory left behind by a manual rm of the wrong thing).

Verify#

orch worktree status

Re-run after a promote/prune/remove to confirm the entry is gone (or no longer flagged dirty/orphan).

Undo#

promote performs a real git merge/rebase into the base branch with no auto-push — if it merged the wrong thing, revert it with normal git (git revert, or reset the base branch if it hasn't been pushed). worktree remove/prune delete local state only; nothing remote is touched.

  • troubleshooting.md — the reaper, abandoned sessions, and stale locks.
  • organise-a-workshop.md — where paths.worktrees sits relative to your projects.