Skip to main content

Delete and Recover a Worktree

Deleting a worktree: what the dialog spells out before you confirm, what force delete costs, what happens to running agents, and the deleted-worktree rescue card that keeps surviving sessions alive.

Updated
Reviewed

Deleting a Worktree

Open the delete dialog by right-clicking a card and choosing Delete Worktree, from the three-dot menu, or from the action palette. The main worktree (your repository root) is protected and can't be deleted.

The dialog fetches a fresh git status when it opens and re-checks it immediately before a force delete dispatches. A backgrounded worktree's cached snapshot can be half a minute old, which would let a force delete skip the typed-name gate and discard work an agent wrote while the dialog was sitting open. If that fresh check fails, the dialog fails closed: it treats the tree as dirty and escalates the confirmation tier.

What will happen

The preview lists the consequences that apply to the current options: deleting the directory, closing the selected terminals, stopping a dev server, discarding tracked or untracked files, and attempting branch deletion. It shows the full worktree path and the actual changed paths before you confirm. Counts the app could not verify are labeled as unknown.

Close all terminals starts checked. Force delete permits discarding uncommitted and untracked files; its label names the kind of work at risk. Delete branch requests Git's safe branch deletion. Even with Force delete checked, an unmerged branch is kept if Git refuses to remove it. The worktree can therefore disappear while its branch remains available for a later checkout.

Worktrees containing submodules

The preview inspects direct submodule work as well as the parent repository. Inside submodules lists nested modified and untracked files, and commits that are not reachable from any remote-tracking ref known to this clone. A clean parent status alone is not proof that a submodule has nothing to lose.

  • Nested modified or untracked files require Force delete and the appropriate confirmation.
  • At-risk submodule commits block deletion, including force deletion. Push them from inside the submodule, or fetch there if they are already published, then choose Recheck.
  • An incomplete submodule inspection blocks deletion. Fix the read or Git error and choose Retry.

The host repeats these safeguards on the deletion path, so bulk removal and agent-initiated deletion cannot bypass them. The inventory is bounded and direct-submodule based; a failed or incomplete check is never presented as safe. See the submodule risk contract.

The confirm button

  • Delete worktree: the default, safe path.
  • Force delete worktree: force is on but the action is still low-risk.
  • For a risky force deletion, a typed-name input appears above the footer and the Force delete worktree button stays disabled until the name matches.
Note
Destructive actions sit on three tiers. D1 is a single-click confirm, D2 adds a checkbox or option gate, D3 requires typing the target name. Worktree delete starts at D2 and escalates to D3 when force delete meets a dirty or protected target, and it re-derives that tier from live git state at submit, not from what it saw at open.

Progress, failure and abandonment

On confirm the dialog closes and the card takes over: the recipe row becomes a Deleting… spinner, the card dims and stops accepting clicks, and it stays mounted until the delete finishes. A failure shows an inline banner titled Couldn't delete worktree with the error text and Retry and Dismiss buttons. The banner sits outside the collapsible details, so collapsing the card doesn't hide it.

Dismissing a failed attempt clears its error state. Dismissing while a host request is still in flight does not cancel that request; Daintree continues tracking its result rather than pretending the deletion stopped.

The card menu grows a separate Force Delete entry when a worktree has running processes, an in-flight teardown, or a previous deletion that timed out. It opens the same dialog with force pre-checked and a shorter teardown timeout.

To delete several worktrees at once, see Worktrees Overview.

Deleted Worktrees

Deleting a worktree does not have to kill the agents running in it. Close all terminals is checked by default in the delete dialog; uncheck it and the directory goes while the terminals keep running, with the row surviving in the sidebar as a deleted-worktree card, a rescue surface with a visible countdown.

The card deliberately shares the live card's design: same header scale, the same terminal section with its collapsed "N active" bar and expandable rows, and the same select-on-click behavior, so activating it shows its surviving terminals in the grid and dock. What marks it as deleted is a FolderX icon, a Deleted pill, the struck-through path and a slight fade that lifts on hover and focus. A trash button in the header, labeled Close N terminals, ends the survivors before the timer does; it asks for confirmation first, and the countdown holds while that confirmation is open.

Rescuing a session means dragging its terminal out onto a live worktree, or using Move to worktree from the terminal's menu. A deleted row never accepts a terminal dropped onto it: it is excluded from the drop-target machinery by construction, not by a flag.

The row anchors itself to the live neighbor it sat above when it was deleted, so the terminals you are looking for stay roughly where you left them instead of jumping to the end of the list. Once two or more pile up they collapse into a single group row with one bulk clear and a rail carrying every surviving terminal, each still draggable.

The directory is already gone; the surviving terminal runs on until the countdown ends

The countdown

Leftover terminals move to trash when the timer ends, after which the row prunes itself. Deleted rows are deliberately ephemeral and never survive a restart.

The countdown measures time you could actually have seen it, not wall time. It refuses to run while the project's view is cached or the window is hidden, and credits any gap it finds on the way back. It also holds (pinned at whatever remained, not reset) while firing would break something:

HoldLabelWhy
A drag is in progressDraggingDragging a terminal out is the rescue gesture; expiring mid-drag would yank the source away.
The row's close confirmation is openConfirmingYou are mid-decision.
A surviving agent is still workingAgent workingActive output resets the idle clock.

Every hold is capped, so a condition that never clears can't pin a row open forever: five minutes for a drag or a confirmation, an hour for a working agent. The row says which condition is holding it, then the preserved countdown resumes.

Set the timer in Settings > Worktree > Deleted worktrees: 30 seconds, 1 minute (default), 5 minutes, or Never (close manually).