Command in version-control
clean-branches
List local Git branches that are fully merged or stale and delete them safely after showing what would be removed, protecting main, master, develop, and the current branch. Pass --dry-run to preview. Unlike the finish-branch skill, which closes one active branch, this cleans up accumulated branches across the repository. Use when local branches have piled up and need safe cleanup.
- Arguments
- [--dry-run]
- Model
- inherit
- Allowed tools
- Bash(git:*)
Install
As a plugin
Bundled in the git plugin. Add the marketplace once, then install the bundle; it updates with the marketplace.
/plugin marketplace add KhaledSaeed18/dotclaude/plugin install git@dotclaudeAs a single item
Run from the project root; the command lands under .claude/. Copy it to ~/.claude/ to make it global.
npx shadcn@latest add KhaledSaeed18/dotclaude/clean-branchesFiles installed
.claude/commands/clean-branches.md
What it does
Context
Options: $ARGUMENTS
Current branch and remotes:
!git branch --show-current 2>/dev/null
!git remote -v 2>/dev/null | head -4
Task
Identify merged and stale local branches and remove them, after presenting a clear list of what will be deleted and why.
Step 1: Gather branch state
# All local branches with their last commit date and whether they are merged into main/master
git branch -v --merged main 2>/dev/null || git branch -v --merged master 2>/dev/null
# Branches with no corresponding remote-tracking ref (orphaned after remote deletion)
git branch -vv | grep ": gone]"
# All local branches with last commit date, sorted oldest first
git for-each-ref --sort=committerdate refs/heads/ \
--format="%(committerdate:short) %(refname:short) %(upstream:track)"
Step 2: Classify branches for deletion
Candidates for deletion are branches that meet one or more of these criteria:
- Fully merged: the branch tip is reachable from
mainormaster(shown bygit branch --merged). - Remote gone: the tracking remote branch was deleted (shown by
": gone]"ingit branch -vv). - Stale and inactive: last commit is more than 90 days old and the branch has no open remote counterpart.
Protected branches - never delete:
main,master,develop,dev,staging,production- The currently checked-out branch
- Any branch with uncommitted changes (this cannot happen for local branches, but note it as a constraint)
Build two lists:
- Safe to delete: merged or remote-gone branches that are not protected.
- Needs review: stale branches that are not merged and whose remote still exists (present these for manual decision, do not auto-delete).
Step 3: Confirm and act
Present the lists clearly before deleting anything:
Branches to delete (merged or remote-gone):
feature/old-login last commit: 2024-11-03 [merged into main]
fix/typo-in-readme last commit: 2025-01-14 [remote: gone]
Branches for manual review (stale, not merged):
experiment/new-nav last commit: 2024-09-12 [remote still exists]
If $ARGUMENTS contains --dry-run, stop here and print the lists without deleting anything.
Otherwise, ask: "Delete the N branches above? (yes/no)" and wait for confirmation before proceeding.
On confirmation, delete each safe branch:
git branch -d <branch-name> # for merged branches (safe delete, errors if not merged)
git branch -D <branch-name> # for remote-gone branches (force delete, only after showing the user)
Use -d (safe) for merged branches. Use -D (force) only for branches confirmed as remote-gone, and log each one explicitly.
Step 4: Report
After deletion, report:
- How many branches were deleted
- Whether any deletion failed and why
- Any branches in the "needs review" list that the user should decide on manually
Optionally offer: git remote prune origin to also clean up stale remote-tracking refs if any were found.
This is the command as installed, rendered from its source on GitHub. Read it as Markdown.
More in version-control
- commitCreate one well-formed commit from the current changes using the git-commit skill's rules: inspect the diff, honour the repo's commitlint and hooks, stage...
- prTake the current branch from uncommitted work to an open pull request: commit outstanding changes with the git-commit rules if asked, push with upstream...
- changelogGenerate a changelog or release notes from Git history, grouped by change type, written in user-facing language, with issue/PR links and breaking changes...
- finish-branchWrap up a completed development branch by verifying tests pass, detecting the workspace state, then presenting clear merge / PR / keep / discard options...
- git-commitCommit work the right way by gathering full repo state, respecting the project's commitlint/pre-commit/branch rules, staging only understood files, and...
- git-undoRecover safely from Git mistakes such as discard, unstage, amend, reset, revert, restore lost commits via reflog, recover deleted branches, and fix bad...