Prune old and merged feature branches. Safely removes local and remote branches after merge.
From atn-claudecode-confignpx claudepluginhub adtechnacity/atn-claudecode-configSafely identify and remove git branches that have been merged into the base branch.
SAFETY: Dry-run by default. Use --execute to actually delete branches.
Can be run standalone or as part of repository maintenance.
Related: /cleanup, /rollback
--execute - Actually delete branches (default is dry-run)--local-only - Only prune local branches--remote-only - Only prune remote branches--exclude <pattern> - Additional branch patterns to protectgit fetch --prune
Auto-detect the default branch (main or master):
BASE=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')
if [ -z "$BASE" ]; then
# Fallback: check which exists
if git show-ref --verify --quiet refs/heads/main; then
BASE="main"
else
BASE="master"
fi
fi
Protected branches (never delete):
--exclude patternFind merged local branches:
git branch --merged $BASE | grep -vE '^\*|^\s*(main|master|dev|develop|staging|production)\s*$'
Find merged remote branches:
git branch -r --merged origin/$BASE | grep -vE 'origin/(main|master|dev|develop|staging|production|HEAD)'
IMPORTANT: Before suggesting release branches for deletion, verify they have been properly released.
For each branch matching release/* or release-* pattern:
Extract version from branch name (e.g., release/v1.2.0 → v1.2.0)
Check for corresponding tag:
git tag -l "v1.2.0" "1.2.0" # Check both with and without 'v' prefix
Check for GitHub release (if gh CLI available):
gh release view v1.2.0 --json tagName 2>/dev/null
Classification:
Display release branch status:
### Release Branch Verification
| Branch | Tag | Release | Status |
| -------------- | ---------- | ----------- | -------------------- |
| release/v1.2.0 | ✅ v1.2.0 | ✅ Released | Safe to prune |
| release/v1.3.0 | ✅ v1.3.0 | ❌ Missing | ⚠️ Warn before prune |
| release/v1.4.0 | ❌ Missing | ❌ Missing | 🛡️ Protected |
Automatic protection: Release branches without a corresponding tag are automatically excluded from the prune candidates and added to the protected list.
Show all branches that would be deleted:
## Branches to Prune
### Local Branches
- feature/old-feature
- fix/completed-bugfix
### Remote Branches
- origin/feature/old-feature
- origin/fix/completed-bugfix
Total: X local, Y remote branches
If --execute was NOT provided:
--execute to deleteIf --execute WAS provided:
git branch -d <branch>git push origin --delete <branch>## Prune Results
### Deleted
- Local: X branches
- Remote: Y branches
### Skipped (protected)
- main, develop, etc.
### Release Branches Protected (no tag/release)
- release/v1.4.0 - No tag found
### Errors (if any)
- [branch]: [error message]
--execute is usedgit branch --merged--execute