Skip to main content

ensure_worker_worktree

Function ensure_worker_worktree 

Source
pub fn ensure_worker_worktree(
    repo: &Path,
    label: &str,
    path: &Path,
) -> Result<WorktreeEnsure, WorktreeError>
Expand description

Recreate the worker worktree at path when a despawn removed it, so a resumed worker can run with its worktree as cwd again - the transcript lives under the worktree’s storage key, so claude --resume cannot find it from any other directory. Anchored on the branch: attach the surviving worktree-<label> when despawn kept it, otherwise recreate the branch from origin/<default-branch> - the base claude’s own --worktree <label> uses under its default worktree.baseRef of fresh.

worktree.baseRef = "head" is not honoured. forge always cuts from the origin base and falls back to the local HEAD only when the repo names no origin/HEAD, or names one that no longer resolves.

A path that exists is judged by its REGISTRATION, not its presence: a worktree git still lists is reused, while a leftover directory git no longer tracks - a despawn’s removal failed part-way, and git deregisters a path before it walks the tree - is cleared deliberately before the add below, because worktree add refuses a path that exists and a resume that died on git’s refusal surfaced as the transport’s message rather than git’s (#1767). An out-of-band delete still defeats this (git’s stale registration makes worktree add fail with git’s message, surfaced here).

A registration git lists by the path the repo has left (a move) is repaired with git worktree repair before it is reused: without that, AlreadyPresent would hand the resume a directory where every git command exits 128. A repair git refuses is a refusal here.

What the clearing trusts, stated plainly: that this state is the tail of a removal the despawn admitted (its dirty verdict, or an explicit force) - nothing in this call re-reads the tree. The record remove_owned_worktree wrote before that removal is what proves it where the link cannot, so a pruned live worktree after a move is refused and kept. Committed work lives on the branch, which is never touched here; what could be lost if the record were wrong is uncommitted/untracked files in a directory that is no longer a worktree.