The pollinations/pollinations repository had accumulated 2,878 remote branches, many of which were:
- Stale from merged pull requests
- Old feature branches
- Abandoned work
This created repository hygiene issues and made it difficult to navigate active development.
File: .github/workflows/cleanup-stale-branches.yml
Features:
- Dry-run mode: Preview deletions before executing
- Batch processing: Process branches in configurable batches (default 50)
- Multiple filters:
merged-prs: Branches from merged pull requests (safest)old-issue: Issue branches older than 6 monthsold-feature: Feature branches older than 6 monthsall: All branches older than 6 months
- Safety measures:
- Protected branch list (main, master, develop, staging, production)
- Rate limiting between deletions
- Artifact uploads for audit trail
- Manual trigger: workflow_dispatch only (no automatic execution)
File: BRANCH_CLEANUP.md
Includes:
- How to use the GitHub Actions workflow
- Manual cleanup instructions with bash scripts
- Branch categorization guide
- Safety measures and best practices
- Troubleshooting section
- Expected outcomes
File: scripts/analyze-branches.sh
A bash script to quickly analyze branch types:
- Count total branches
- Identify protected branches
- Count by category (issue-numbered, feature, copilot, add-*)
- Sample recent vs old branches
- Provide cleanup recommendations
-
Initial Analysis:
./scripts/analyze-branches.sh
-
First Cleanup (Dry Run):
- Go to Actions → "Clean Up Stale Branches"
- Configure:
- dry_run:
true - branch_filter:
merged-prs - batch_size:
50
- dry_run:
- Click "Run workflow"
- Download and review the artifact
-
Execute Cleanup:
- Same as above but set dry_run:
false - Repeat as needed for remaining branches
- Same as above but set dry_run:
-
Review Progress:
git fetch --all --prune git branch -r | grep -v '\->' | wc -l
- Merged PR branches (safest) - issue-numbered branches like
664-feature-name - Old feature branches - feature/fix/hotfix branches > 6 months old
- Old issue branches - issue branches > 6 months old
- Other old branches - after careful review
The implementation includes multiple safety layers:
- Hard-coded protected branches that can never be deleted
- Dry-run mode is the default
- Manual trigger only - no automatic cleanup
- Batch processing prevents overwhelming the system
- Audit trail via workflow artifacts
- Rate limiting to avoid API issues
Target: Reduce from ~2,878 branches to ~50-100 active branches
Benefits:
- Improved git performance
- Easier navigation of active work
- Better repository hygiene
- Clearer view of ongoing development
Based on analysis of the repository:
-
Issue-numbered branches (e.g.,
664-feature,1234-fix-bug)- Typically created from GitHub issues/PRs
- Safe to delete if PR is merged or closed
-
Feature branches (e.g.,
feature/xyz,fix/abc,hotfix/urgent)- Development branches
- Check for open PRs before deleting
-
Add- branches* (e.g.,
add-new-project)- Usually project submissions
- Check if PR was merged
-
Copilot branches (e.g.,
copilot/task-name)- GitHub Copilot generated branches
- Review activity before deleting
-
Other patterns (e.g.,
hacktoberfest/*, date-based, etc.)- Case-by-case review needed
The workflow script:
- Fetches all remote branches
- Filters based on selected category
- Checks against protected branch list
- For merged-prs filter: validates PR merge status via GitHub API
- For age-based filters: checks last commit date
- Limits to batch size
- Deletes (or just lists in dry-run mode)
- Saves list to artifact
The cleanup workflow should be run periodically:
- Monthly: For merged PR branches
- Quarterly: For old feature branches
- Annually: Full review of all branches
.github/workflows/cleanup-stale-branches.yml (new)
BRANCH_CLEANUP.md (new)
scripts/analyze-branches.sh (new)
✅ CodeQL analysis passed with 0 alerts ✅ No secrets or credentials in code ✅ Requires write permissions (controlled by repository settings) ✅ Manual trigger only (no automatic execution)
For repository maintainers:
- Review this implementation
- Test with dry-run mode
- Execute cleanup in batches
- Monitor progress
- Schedule periodic cleanups
Note: This implementation provides the tools but does not automatically delete any branches. All deletions must be manually triggered by repository maintainers with appropriate permissions.