From git
Identifies and removes old, merged, or defunct git branches from local and remote repositories with safety checks for protected branches.
How this command is triggered — by the user, by Claude, or both
Slash command
/git:branch-cleanup [--dry-run] [--merged-only] [--remote]The summary Claude sees in its command listing — used to decide when to auto-load this command
## Name git:branch-cleanup ## Synopsis ## Description The `git:branch-cleanup` command identifies and removes old, defunct, or merged branches from your local repository (and optionally from remote). It helps maintain a clean repository by removing branches that are no longer needed, such as: - Branches that have been merged into the main branch - Branches that no longer exist on the remote - Stale feature branches from completed work The command performs safety checks to prevent deletion of: - The current branch - Protected branches (main, master, develop, etc.) - Branches with unmerge...
git:branch-cleanup
/git:branch-cleanup [--dry-run] [--merged-only] [--remote]
The git:branch-cleanup command identifies and removes old, defunct, or merged branches from your local repository (and optionally from remote). It helps maintain a clean repository by removing branches that are no longer needed, such as:
The command performs safety checks to prevent deletion of:
The spec sections is inspired by https://man7.org/linux/man-pages/man7/man-pages.7.html#top_of_page
The command should follow these steps:
Identify Main Branch
git symbolic-ref refs/remotes/origin/HEAD or git branch -r to determineGather Branch Information
git branchgit branch --show-currentgit branch --merged <main-branch>git log <main-branch> --merges --onelinegit diff <main-branch>...<branch> --quietgit cherry <main-branch> <branch>git branch -vvgit remote prune origin --dry-runCategorize Branches
Present Analysis to User
Confirm Deletion
--dry-run flag is present, only show what would be deletedDelete Branches
git branch -d <branch> (merged) or git branch -D <branch> (force)--remote flag): git push origin --delete <branch>git remote prune originReport Results
Implementation logic:
# Determine main branch
main_branch=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')
if [ -z "$main_branch" ]; then
main_branch="main" # fallback
fi
# Get current branch
current_branch=$(git branch --show-current)
# Multi-layered merge detection function
# Returns: "merged:<method>" or "not-merged"
check_if_merged() {
local branch=$1
local main_branch=$2
# Escape for grep ERE: ] [ \ . ^ $ * + ? ( ) { } |
local branch_escaped=$(printf '%s\n' "$branch" | sed -e 's/[][\\.^$*+?(){}|]/\\&/g')
# Method 1: Standard merge check (commits in main history)
if git branch --merged "$main_branch" | grep -q "^[* ]*${branch_escaped}$"; then
echo "merged:standard"
return 0
fi
# Method 2: Merge-commit message heuristic (requires branch mention)
# Matches examples: "Merge branch 'X'", "Merge pull request ... from org/X"
# Note: Squash merges are not --merges; those are covered by Method 3 (content-identical).
local branch_basename=${branch##*/}
local branch_basename_escaped
branch_basename_escaped=$(printf '%s\n' "$branch_basename" | sed -e 's/[][\\.^$*+?(){}|]/\\&/g')
if git log "$main_branch" --merges --oneline \
| grep -qiE "merge.*(branch[[:space:]]+'${branch_escaped}'|\b${branch_escaped}\b|from[[:space:]]+[^[:space:]]*/${branch_basename_escaped})"; then
echo "merged:merge-commit"
return 0
fi
# Method 3: Content comparison (handles rebased/cherry-picked branches)
# Uses three-dot syntax (merge-base comparison) to detect content-identical branches
# If diff is empty, all content is in main even if commit hashes differ
# Note: 2>/dev/null suppresses errors for edge cases (no common ancestor, invalid branch)
if git diff --quiet "$main_branch"..."$branch" 2>/dev/null; then
echo "merged:content-identical"
return 0
fi
# Method 4: Cherry-pick detection (all commits have equivalents in main)
# Commits prefixed with '-' have equivalent patches in main
# Note: Detects patch equivalence, not necessarily commits reachable from main
# May have rare false positives with coincidentally similar commits
local unmerged=$(git cherry "$main_branch" "$branch" 2>/dev/null | grep -c '^+')
if [ "$unmerged" -eq 0 ]; then
echo "merged:cherry-picked"
return 0
fi
echo "not-merged"
return 1
}
# Find all merged branches with detection method
for branch in $(git branch | grep -v "^\*" | sed 's/^[ ]*//'); do
if [ "$branch" != "$main_branch" ]; then
merge_status=$(check_if_merged "$branch" "$main_branch")
if [[ "$merge_status" == merged:* ]]; then
method=${merge_status#merged:}
echo "$branch|$method"
fi
fi
done
# Find branches with deleted remotes ("gone")
git branch -vv | grep ': gone]' | awk '{print $1}'
# Find stale branches (older than 3 months)
git for-each-ref --sort=-committerdate --format='%(refname:short)|%(committerdate:iso)|%(upstream:track)' refs/heads/
# Delete local branch (merged)
git branch -d <branch-name>
# Delete local branch (force)
git branch -D <branch-name>
# Delete remote branch
git push origin --delete <branch-name>
# Prune remote references
git remote prune origin
Basic usage (interactive):
/git:branch-cleanup
Output:
Analyzing branches in repository...
Main branch: main
Current branch: feature/new-api
=== Merged Branches (safe to delete) ===
feature/bug-fix-123 Merged (standard) - 2 weeks ago
feature/update-deps Merged (merge-commit) - 1 month ago
feature/rebased-work Merged (content-identical) - 3 days ago
=== Gone Branches (remote deleted) ===
feature/old-feature Remote: gone
hotfix/urgent-fix Remote: gone
=== Stale Branches (no activity > 3 months) ===
experiment/prototype Last commit: 4 months ago, not merged
=== Protected Branches (will not delete) ===
main
develop
Recommendations:
- Safe to delete: feature/bug-fix-123, feature/update-deps (merged)
* Note: feature/rebased-work has different commits but identical content (rebased)
- Safe to delete: feature/old-feature, hotfix/urgent-fix (remote gone)
- Review needed: experiment/prototype (unmerged, stale)
What would you like to delete?
Dry run (preview only):
/git:branch-cleanup --dry-run
Output:
[DRY RUN MODE - No changes will be made]
Would delete the following merged branches:
- feature/bug-fix-123
- feature/update-deps
Would delete the following gone branches:
- feature/old-feature
- hotfix/urgent-fix
Total: 4 branches would be deleted
Merged branches only:
/git:branch-cleanup --merged-only
Output:
Analyzing merged branches...
Found 3 merged branches:
- feature/bug-fix-123
- feature/update-deps
- feature/ui-improvements
Delete these branches? (y/n)
Including remote cleanup:
/git:branch-cleanup --remote
Output:
Deleting local and remote branches...
✓ Deleted local: feature/bug-fix-123
✓ Deleted remote: origin/feature/bug-fix-123
✓ Deleted local: feature/update-deps
✓ Deleted remote: origin/feature/update-deps
Summary: Deleted 2 branches locally and remotely
--dry-run: Preview which branches would be deleted without actually deleting them--merged-only: Only consider branches that have been fully merged into the main branch--remote: Also delete branches from the remote repository (requires push permissions)--force: Force delete branches even if they have unmerged commits (use with caution)--older-than=<days>: Only consider branches with no commits in the last N days (default: 90)--force is used--remote flagnpx claudepluginhub bryan-cox/ai-helpers --plugin git/clean-branchesIdentifies merged and stale git branches, then interactively deletes them after safety checks and user confirmation.
/cleanup-branchesDeletes local (and optionally remote) branches merged into base branch (default: main), flags stale unmerged branches for review, produces cleanup summary with dry-run option.
/branch-cleanupAnalyzes and cleans up merged, stale, and old branches with safety checks. Supports dry-run, force, remote-only, and local-only modes.
/branch-cleanupFetches and prunes merged local and stale branches, with optional remote cleanup and dry-run preview.
/branch-cleanupScans local and remote git branches, classifies them as safe to delete, possibly stale, or keep, and prints deletion commands for review.