| name | git-branch-cleanup |
| description | Automatically clean up merged branches, stale remotes, and organize repository structure. Use this skill when you notice merged branches, stale remote-tracking branches, cluttered branch lists, or when completing feature work. Trigger for phrases like "clean up branches", "delete merged branches", "prune remotes", "organize git", or when branch count exceeds 10-15 active branches. Also activate proactively after PR merges or when git branch output shows many [gone] references. |
| allowed-tools | ["Bash","Read"] |
Git Branch Cleanup
You are an expert at Git branch management, specializing in safe cleanup of merged branches and repository organization.
When to Use This Skill
Use this skill whenever:
- You notice many merged branches in
git branch output
- Remote-tracking branches show
[gone] status
- The repository has more than 10-15 active branches
- After completing and merging a pull request
- The user mentions "cleanup", "organize", or "delete branches"
- Git operations are slow due to too many branch references
Safety Principles
Never delete:
- Main branches:
main, master, develop, staging, production
- Release branches:
release/* patterns
- The current branch (always check
git branch --show-current)
- Branches with unmerged work (unless explicitly requested)
Always:
- Verify branch merge status before deletion
- Keep backup references via reflog (30-day recovery window)
- Show dry-run output before destructive operations
- Confirm with user for force deletions
Core Workflow
Step 1: Analyze Current State
First, gather repository information:
git branch --show-current
git branch -vv
git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)|%(committerdate:relative)|%(upstream:track)' | head -20 | column -t -s '|'
git branch --merged main 2>/dev/null || git branch --merged master 2>/dev/null
Present a summary to the user:
- Total branches: local and remote
- Merged branches (safe to delete)
- Stale branches (no activity in 30+ days)
- Gone branches (remote deleted but local remains)
Step 2: Categorize Branches
Safe to delete (merged):
git branch --merged main | grep -v "^\*\|main\|master\|develop"
Gone branches (remote deleted):
git branch -vv | grep ': gone]'
Stale branches (old but not merged):
git for-each-ref --sort=committerdate refs/heads/ --format='%(refname:short)|%(committerdate:relative)' | grep -E 'months|years' ago
Step 3: Present Cleanup Plan
Before making changes, show the user:
Branch Cleanup Plan
-------------------
Safe to delete (merged): 8 branches
- feature/user-auth (merged 2 weeks ago)
- bugfix/login-error (merged 1 month ago)
- ...
Gone remotes: 3 branches
- feature/old-feature (remote deleted)
- ...
Stale branches: 2 branches (require confirmation)
- experiment/new-ui (6 months old, not merged)
- ...
Protected: main, develop, staging (kept)
Ask: "Should I proceed with cleanup? (safe only / all / cancel)"
Step 4: Execute Cleanup
Delete merged branches:
git branch --merged main | grep -v "^\*\|main\|master\|develop" | xargs -n 1 git branch -d
git branch -r --merged main | grep -v "main\|master\|develop\|HEAD" | sed 's/origin\///' | xargs -n 1 git push origin --delete
Clean gone branches:
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -n 1 git branch -D
Prune remote references:
git remote prune origin
git remote | xargs -n 1 git remote prune
Step 5: Verify and Report
After cleanup:
git branch -a
git reflog --no-merges --since="1 week ago" | head -20
Generate a report:
Branch Cleanup Complete
-----------------------
Deleted 8 merged local branches
Removed 3 gone tracking branches
Pruned 5 stale remote references
Before: 23 branches
After: 10 branches
Recovery available via reflog for 30 days.
Run `git reflog` to see recent deletions.
Advanced Operations
Delete Unmerged Branches (Risky)
Only with explicit user confirmation:
git branch -D branch-name
git rev-parse branch-name
echo "To recover: git checkout -b branch-name abc123def456"
Bulk Remote Cleanup
git branch -r --merged main | grep origin | grep -v 'main\|master\|develop\|HEAD'
git branch -r --merged main | grep origin | grep -v 'main\|master\|develop\|HEAD' | sed 's/origin\///' | xargs -n 1 git push origin --delete
Sync with GitHub PR Status
If gh CLI is available:
gh pr list --state merged --json headRefName --jq '.[].headRefName'
gh pr list --state merged --json headRefName --jq '.[].headRefName' | xargs -n 1 git branch -d
Recovery Procedures
Recover Recently Deleted Branch
git reflog --no-merges --since="2 weeks ago" | grep -i "branch-name"
git checkout -b branch-name <commit-hash>
Restore All Recent Deletions
git reflog --date=relative | grep 'moving from' | head -20
git reflog | grep 'branch:' | head -20
Command Modes
Dry Run (default)
Show what would be deleted without making changes:
git branch --merged main | grep -v "^\*\|main\|master\|develop"
Interactive Mode
Confirm each deletion:
git branch --merged main | grep -v "^\*\|main\|master\|develop" | while read branch; do
echo "Delete $branch? (y/n)"
read answer
if [ "$answer" = "y" ]; then
git branch -d "$branch"
fi
done
Force Mode
Delete without confirmation (use carefully):
git branch --merged main | grep -v "^\*\|main\|master\|develop" | xargs -n 1 git branch -d
Best Practices
- Run git fetch before cleanup - Ensure branch merge status is current
- Check git status - No uncommitted changes in the current branch
- Use -d (lowercase) for merged - Safer than -D (force)
- Keep reflog accessible - Don't run git gc during cleanup
- Document large cleanups - Note what was deleted and why
- Test in dry-run first - Always preview before executing
Common Patterns
Weekly Maintenance:
git fetch --all --prune
git branch --merged main | grep -v "^\*\|main\|master\|develop" | xargs -n 1 git branch -d
git remote prune origin
Post-Release Cleanup:
git branch | grep 'release/' | grep -v "$(git branch --show-current)" | xargs -n 1 git branch -d
Pre-PR Review:
git fetch origin main:main
git branch --merged main | grep -v "^\*\|main" | xargs -n 1 git branch -d
Output Format
Always provide a structured summary:
Git Branch Cleanup Report
=========================
Date: YYYY-MM-DD HH:MM
Summary
-------
Action: [Dry Run / Cleanup Executed]
Branches analyzed: N
Branches deleted: N
Remote references pruned: N
Details
-------
Deleted merged branches:
- feature/user-auth (merged 2024-02-15)
- bugfix/login-fix (merged 2024-02-20)
Gone tracking branches removed:
- feature/experiment (remote deleted)
Protected (kept):
- main
- develop
- current-feature
Recovery
--------
All deletions are recoverable via reflog for 30 days.
To see recent changes: git reflog --date=relative | head -20
To recover a branch: git checkout -b <branch-name> <commit-hash>
Next Steps
----------
Repository is now organized with N active branches.
Consider running this cleanup monthly or after major releases.
Remember
The goal is to maintain a clean, organized repository without losing work. Always err on the side of caution - it's better to keep an extra branch than to lose important work. Recovery via reflog is possible but prevention is better.