A fast CLI tool to delete local Git branches that have already been merged into a target branch.
- Detects merged branches using commit graph analysis (
git2) - Skips the current branch and the base branch automatically
- Colour-coded output for quick scanning
--dry-runmode to preview changes before acting--interactivemode with a keyboard checklist to pick which branches to delete--forceflag to skip confirmation--ignorelist to protect specific branches
Use the automated install script:
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/Dave136/cleanup-branches/main/install.sh | shThe default installation directory is ~/.local/bin. To install elsewhere, set the DIR variable:
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/Dave136/cleanup-branches/main/install.sh | DIR=/usr/local/bin shOr download and extract a release manually from the releases page.
Requires Rust (edition 2024, stable toolchain).
git clone <repo-url>
cd cleanup-branches
cargo build --releaseThe binary will be at target/release/cleanup-branches. Copy it anywhere on your $PATH:
cp target/release/cleanup-branches ~/.local/bin/Create a shorter alias (cb):
Add to your shell configuration (.bashrc, .zshrc, etc.):
alias cb='cleanup-branches'Or install via cargo and create a system-wide symlink:
# Install with cargo
cargo install --path .
# Create symlink in /usr/bin (requires sudo)
sudo ln -s ~/.cargo/bin/cleanup-branches /usr/bin/cleanup-branches
# Optional: also symlink the short alias
sudo ln -s ~/.cargo/bin/cleanup-branches /usr/bin/cbcleanup-branches <repo-path> <base-branch> [OPTIONS]
| Argument | Description |
|---|---|
<repo-path> |
Path to the Git repository |
<base-branch> |
Branch to check merged status against |
| Option | Short | Description |
|---|---|---|
--force |
-f |
Delete without asking for confirmation |
--dry-run |
-d |
Show what would be deleted without making changes |
--interactive |
— | Open a checklist to toggle which merged branches to delete |
--ignore <LIST> |
-i |
Comma-separated branch names to keep |
--help |
-h |
Print help |
With --interactive, an opt-in checklist lists every eligible merged branch, each labelled with the branch it was merged into (e.g. feature-x (merged into 'main')). Every branch starts selected. Current and ignored branches stay visible as skipped but cannot be selected.
| Key | Action |
|---|---|
Space |
Toggle a branch |
Enter |
Confirm the selection |
Esc / q |
Cancel (delete nothing) |
--interactive cannot be combined with --force; the selection itself is the confirmation.
# Preview branches that would be deleted
cleanup-branches /path/to/repo main --dry-run
# Delete merged branches, prompting for confirmation
cleanup-branches /path/to/repo main
# Delete without confirmation
cleanup-branches /path/to/repo main --force
# Keep specific branches even if merged
cleanup-branches /path/to/repo main --ignore hotfix,staging,release
# Interactively select which merged branches to delete
cleanup-branches /path/to/repo main --interactive
# Preview the interactive selection without deleting
cleanup-branches /path/to/repo main --interactive --dry-run
# Check against a different base branch
cleanup-branches /path/to/repo developThe tool opens the repository with git2 and fetches the latest state of the base branch from origin. It then iterates over all local branches and computes graph_ahead_behind(branch, base). Any branch with ahead == 0 is fully merged into the base — identical to what git branch --merged reports — and is a candidate for deletion.
| Crate | Purpose |
|---|---|
clap |
CLI argument parsing |
dialoguer |
Interactive checklist prompt |
git2 |
Libgit2 bindings for repository operations |
anyhow |
Ergonomic error handling |