with one click
prune-merged
Clean up local branches that have been merged into main.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Clean up local branches that have been merged into main.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Capture session learnings and save to skills, guidelines, or reference docs under ~/.claude/.
Orchestrate parallel claude -p sessions — bootstrap, launch, monitor, and converge. Works with any skill that produces manifest.json, item directories, and a runner script.
Create a request (pull request or merge request) or update an existing one following project conventions.
Resolve merge or rebase conflicts between branches.
Assess open PRs with unaddressed review comments and generate a parallel addressing script — produces manifest.json and let-it-rip.sh for address-request-comments execution.
Assess open work items and generate a parallel execution script — produces manifest.json and let-it-rip.sh for implement/clarify execution.
| name | prune-merged |
| description | Clean up local branches that have been merged into main. |
| allowed-tools | ["Read","Bash","AskUserQuestion"] |
Remove local branches that have already been merged into remote main.
/git:prune-merged - List and prune merged branches (with confirmation)/git:prune-merged --dry-run - Only list branches that would be prunedFetch latest from remote:
git fetch origin --prune
Find merged branches (store as MERGED_BRANCHES):
Detect branches merged via two methods:
Method A - Regular merges:
git branch --merged origin/main | grep -v '^\*' | grep -v 'main' | grep -v 'master'
Method B - Squash merges (remote branch deleted after PR merge):
# Handle the `+ branch` (worktree-attached) and `* branch` (current) prefixes
# `git branch -vv` adds — `awk '{print $1}'` would extract the marker and silently drop the branch.
git branch -vv | grep ': gone]' | sed 's/^[+* ] *//' | awk '{print $1}'
The sed strips the leading + (worktree-checked-out) or * (current branch) marker that git branch -vv puts in column 1. Without it, awk '{print $1}' returns the marker as a phantom branch name and drops the real one.
Combine both lists, removing duplicates. This catches:
Bucket worktree-attached separately. Lines starting with + in git branch -vv
are checked out in another worktree and cannot be deleted with git branch -D until
detached. Capture them so step 4 can list them as "blocked by worktree" rather than
attempting (and failing) to delete them, and so the operator sees what to detach.
Handle dry-run mode:
$ARGUMENTS contains --dry-run:
Display branches for confirmation:
If MERGED_BRANCHES is empty:
No merged branches to prune. All local branches have unmerged commits.
Exit here.
Otherwise, display:
Found merged branches to prune:
| Branch | Last Commit |
|--------|-------------|
| feature/auth | 3 days ago |
| fix/login-bug | 1 week ago |
If any worktree-attached merged branches were captured in step 2, list them in a separate "Blocked by worktree" table with the worktree path so the operator can detach them and re-run:
Blocked by worktree (skipped — detach with `git worktree remove <path>`):
| Branch | Worktree Path |
|--------|---------------|
| sweep/137-foo | tmp/.../worktrees/issue-137 |
Use AskUserQuestion to confirm:
Delete confirmed branches:
For branches detected via Method A (regular merge):
git branch -d <branch-name>
For branches detected via Method B (squash merge / gone remote):
git branch -D <branch-name>
Note: Method A branches use -d as a safety check. Method B branches
require -D because their commits aren't in main's history (they were
squashed). The "gone" remote is the indicator that the PR was merged.
Report results:
Pruned branches:
- feature/auth
- fix/login-bug
Kept branches:
- (none)
Remaining local branches: 3
$ /git:prune-merged
Fetching latest from origin...
Found merged branches to prune:
| Branch | Last Commit |
|--------|-------------|
| docs/update-readme | 2 days ago |
| feature/add-auth | 1 week ago |
| fix/typo | 3 weeks ago |
? Delete these branches?
> Delete all
Select branches
Cancel
Pruned branches:
- docs/update-readme
- feature/add-auth
- fix/typo
Remaining local branches: 2 (main, feature/in-progress)
-d; squash merges use -D (safe because remote deletion confirms merge)main, master, or the current branchgit fetch origin --pruneorigin/main instead of its own remoteSymptom: A squash-merged branch isn't detected even after git fetch --prune.
Cause: The branch was configured to track origin/main directly instead of origin/<branch-name>. When checking git branch -vv, it shows [origin/main: ahead X] instead of [origin/<branch-name>: gone].
Detection: Method B (git branch -vv | grep ': gone]') fails because origin/main still exists.
Resolution: These branches require manual identification. Check git branch -vv for branches showing [origin/main: ahead X] where the remote branch no longer exists:
# Check if the branch's expected remote exists
git branch -r | grep "<branch-name>"
# If no output, the branch was likely merged and can be deleted with -D
Example: Branch feature/user-settings tracked origin/main instead of origin/feature/user-settings. After the PR was squash-merged and the remote deleted, it showed [origin/main: ahead 3] instead of : gone].