Filed unassigned while doing R21 seat housekeeping (chasing one known orphan branch). Recording it rather than acting: deleting branches is destructive, and nobody has asked for a cleanup.
The measurement
$ git branch -r --list 'origin/claude/*' | wc -l
393
Measured on main @ f01e6f6f.
⚠️ The trap, which is the more useful half of this card
The obvious predicate for "safe to delete" is "has this branch been merged into main?", and the obvious command is:
git rev-list --count origin/main..<branch> # 0 ⇒ fully merged
In this repository that command is meaningless. Landing goes through the merge queue with SQUASH, so a feature branch's own commits never become ancestors of main — the squash commit is a new object with a different tree lineage. Every branch here therefore reports a large non-zero count regardless of whether its work landed. A sample of the run:
origin/claude/agent-metadata-positioning-th5hhm : 1429 commits ahead of main
origin/claude/authorization-gaps-profile-grants-xrcoku : 1436 commits ahead of main
origin/claude/chinese-i18n-issues-lq7hlp : 1587 commits ahead of main
Those numbers are artifacts of squash-merging, not unmerged work. ⇒ Anyone reading them as "1429 commits would be lost" concludes the branches must be kept; anyone reading them as noise and deleting anyway is right by luck, not by measurement. Both readings are unsafe. The sound predicate is the branch's associated PR state (merged / closed / none), which is a GitHub API question, not a git-ancestry one.
⭐ This trap is worth recording even if the cleanup itself is never done, because the same reasoning breaks any future "is this branch landed?" check written locally in this repo.
A confirmed instance
origin/claude/issue-1231-dependabot-second-lockfile is a genuine orphan: its tip is 966cc23b, a squash commit that is already main's history, so the branch carries no commit of its own — it was cut and abandoned when #1231's work was re-cut as claude/issue-1231-retire-package-lock and landed as PR #1469. Zero-own-commit branches like this one are the unambiguously safe class, and they are detectable without touching the API: the tip is reachable from main.
What this costs today
Speculative, and deliberately not asserted as harm: every git fetch and every git worktree add in this repo pays for these refs, and this repo runs several agents in parallel, each creating worktrees. Whether that is measurable has not been measured. ⛔ Do not treat "393 branches" as a demonstrated performance problem — it is a demonstrated inventory.
Not proposed
⛔ No mass deletion is proposed here, and this seat will not perform one on its own initiative. If it is wanted, the shape is: enumerate claude/*, resolve each to its PR via the API, delete only those whose PR is merged, and leave every branch with no PR or an open PR alone. The zero-own-commit subset above could go first as a safe pilot.
Filed unassigned while doing R21 seat housekeeping (chasing one known orphan branch). Recording it rather than acting: deleting branches is destructive, and nobody has asked for a cleanup.
The measurement
Measured on
main@f01e6f6f.The obvious predicate for "safe to delete" is "has this branch been merged into
main?", and the obvious command is:In this repository that command is meaningless. Landing goes through the merge queue with SQUASH, so a feature branch's own commits never become ancestors of
main— the squash commit is a new object with a different tree lineage. Every branch here therefore reports a large non-zero count regardless of whether its work landed. A sample of the run:Those numbers are artifacts of squash-merging, not unmerged work. ⇒ Anyone reading them as "1429 commits would be lost" concludes the branches must be kept; anyone reading them as noise and deleting anyway is right by luck, not by measurement. Both readings are unsafe. The sound predicate is the branch's associated PR state (merged / closed / none), which is a GitHub API question, not a git-ancestry one.
⭐ This trap is worth recording even if the cleanup itself is never done, because the same reasoning breaks any future "is this branch landed?" check written locally in this repo.
A confirmed instance
origin/claude/issue-1231-dependabot-second-lockfileis a genuine orphan: its tip is966cc23b, a squash commit that is alreadymain's history, so the branch carries no commit of its own — it was cut and abandoned when #1231's work was re-cut asclaude/issue-1231-retire-package-lockand landed as PR #1469. Zero-own-commit branches like this one are the unambiguously safe class, and they are detectable without touching the API: the tip is reachable frommain.What this costs today
Speculative, and deliberately not asserted as harm: every
git fetchand everygit worktree addin this repo pays for these refs, and this repo runs several agents in parallel, each creating worktrees. Whether that is measurable has not been measured. ⛔ Do not treat "393 branches" as a demonstrated performance problem — it is a demonstrated inventory.Not proposed
⛔ No mass deletion is proposed here, and this seat will not perform one on its own initiative. If it is wanted, the shape is: enumerate
claude/*, resolve each to its PR via the API, delete only those whose PR is merged, and leave every branch with no PR or an open PR alone. The zero-own-commit subset above could go first as a safe pilot.