Tearing down a merged worktree
git worktree remove cleans up only the checkout. The branch, the Herdr
workspace holding the pane, the setup log, and any per-worktree data
(databases, indexes) outlive it. The bundled script handles all of it except
moving the Claude session, which only ExitWorktree can do.
Script: ~/.claude/skills/tearing-down-a-merged-worktree/scripts/worktree-teardown.sh
(header comment documents the flags).
Runs when the user asks after a merge, or automatically once auto-merge
polling sees MERGED. In the automatic case do not ask, but report.
Steps
If the repo has its own tearing-down-a-merged-worktree skill under
.claude/skills/, follow that one instead. It knows the project's data.
Run:
~/.claude/skills/tearing-down-a-merged-worktree/scripts/worktree-teardown.sh <slug>
<slug> is the dir name under .claude/worktrees/, or any registered
worktree path. The script refuses unless the branch's PR is MERGED
(--pr <n> to name it, --no-pr only when the user confirms there is no
PR). CLOSED is not MERGED: closed-unmerged work exists only in that
checkout. Never bypass this for an open PR.
If the tree is dirty the script stops and shows the changes. Inspect with
the user before re-running with --force. Unmerged work is the one thing
here that cannot be recovered.
The script moves the pane to the repo's home workspace first, creating one
if none exists, then removes checkout and branch, runs the project's
.claude/worktree-teardown.sh <slug> <branch> hook if present, and deletes
the setup log.
If the report ends with a session: line, call ExitWorktree with
action: "keep" now. The session is sitting in a deleted directory.
Relay the report verbatim: branch, worktree, herdr, data hook, log. A
teardown that quietly skipped a step reads exactly like one that worked.
Project hook
<repo>/.claude/worktree-teardown.sh <slug> <branch> (executable) runs from
the main checkout after the git removal. Put database drops, index deletes and
container cleanup there, and make it verify by counting what the server
reports, not by exit code: a drop that matched nothing still exits 0.
Notes
branch -D, not -d: a squash merge leaves the branch looking unmerged.
- Pane and session are two movements.
herdr pane move leaves the session's
cwd behind; ExitWorktree leaves the pane behind. The script does the
first, you do the second.
- The worktree's workspace closes itself when its last pane leaves. The
script closes it explicitly if extra tabs kept it alive.
1---2name: tearing-down-a-merged-worktree3description: Use after a PR has merged and its worktree should be cleaned up (checkout, branch, Herdr workspace, setup log, project data). Triggers on tear down the worktree, clean up the worktree, remove the worktree, teardown after merge, and on an auto-merge poll seeing MERGED. Works in any git repository.4---56# Tearing down a merged worktree78`git worktree remove` cleans up only the checkout. The branch, the Herdr9workspace holding the pane, the setup log, and any per-worktree data10(databases, indexes) outlive it. The bundled script handles all of it except11moving the Claude session, which only `ExitWorktree` can do.1213Script: `~/.claude/skills/tearing-down-a-merged-worktree/scripts/worktree-teardown.sh`14(header comment documents the flags).1516Runs when the user asks after a merge, or automatically once auto-merge17polling sees `MERGED`. In the automatic case do not ask, but report.1819## Steps20211. If the repo has its own `tearing-down-a-merged-worktree` skill under22 `.claude/skills/`, follow that one instead. It knows the project's data.232. Run:2425 ```bash26 ~/.claude/skills/tearing-down-a-merged-worktree/scripts/worktree-teardown.sh <slug>27 ```2829 `<slug>` is the dir name under `.claude/worktrees/`, or any registered30 worktree path. The script refuses unless the branch's PR is `MERGED`31 (`--pr <n>` to name it, `--no-pr` only when the user confirms there is no32 PR). `CLOSED` is not `MERGED`: closed-unmerged work exists only in that33 checkout. Never bypass this for an open PR.343. If the tree is dirty the script stops and shows the changes. Inspect with35 the user before re-running with `--force`. Unmerged work is the one thing36 here that cannot be recovered.374. The script moves the pane to the repo's home workspace first, creating one38 if none exists, then removes checkout and branch, runs the project's39 `.claude/worktree-teardown.sh <slug> <branch>` hook if present, and deletes40 the setup log.415. If the report ends with a `session:` line, call `ExitWorktree` with42 `action: "keep"` now. The session is sitting in a deleted directory.436. Relay the report verbatim: branch, worktree, herdr, data hook, log. A44 teardown that quietly skipped a step reads exactly like one that worked.4546## Project hook4748`<repo>/.claude/worktree-teardown.sh <slug> <branch>` (executable) runs from49the main checkout after the git removal. Put database drops, index deletes and50container cleanup there, and make it verify by counting what the server51reports, not by exit code: a drop that matched nothing still exits 0.5253## Notes5455- `branch -D`, not `-d`: a squash merge leaves the branch looking unmerged.56- Pane and session are two movements. `herdr pane move` leaves the session's57 cwd behind; `ExitWorktree` leaves the pane behind. The script does the58 first, you do the second.59- The worktree's workspace closes itself when its last pane leaves. The60 script closes it explicitly if extra tabs kept it alive.