git-broom
git-broom is a small Rust CLI for cleaning up stale local git branches after squash-merge workflows leave tracking branches behind.
It is designed to be safe to browse often and destructive only on purpose:
git-broomshows a grouped preview by defaultgit-broom cleanenters the interactive destructive workflow--batchand--dry-runare compatibility aliases for the same grouped preview
Current behavior focuses on grouped branch review:
gone: branches whose upstream tracking ref is[gone]unpushed: local branches with no upstream configuredpr: remote-tracked branches with an open PR on GitHubnopr: remote-tracked branches with no PR on GitHubclosed: remote-tracked branches whose PR is closed on GitHubmerged: remote-tracked branches whose PR is merged but whose remote branch still existssin interactive mode saves or unsaves a branch for this repo and cleanup mode
Requirements
git- Rust toolchain with
rustfmtandclippy ghwith an authenticated session if you want to use the GitHub-backed groups (pr,nopr,closed,merged)
This repo includes rust-toolchain.toml so a standard Rust setup can install the right components automatically.
If you use mise, that is still fine; mise can manage the Rust toolchain, but no extra repo-specific mise config is required here.
Running locally
That previews all implemented review groups without deleting anything.
To enter the destructive workflow:
That walks the selected groups one by one, lets you save or mark branches for deletion, and asks for confirmation before running cleanup commands for each group.
Other modes:
pr is preview-only. git-broom clean rejects it so destructive review only covers cleanup candidates.
Saved branches are cached locally under the repo's git metadata directory, not in tracked files. In a normal clone that path is .git/git-broom/keep-labels.json; in worktree setups it resolves through the shared git common dir.
GitHub-backed preview also caches PR metadata locally at .git/git-broom/pr-cache.json. That cache speeds up repeated preview runs, but git-broom clean --groups nopr,closed,merged refreshes GitHub data before destructive review so cleanup does not rely on stale PR metadata.
Within each review group, branches are shown in this order:
- protected branches first
- saved branches next
- regular cleanup candidates last
Saved branches stay visible in both the TUI and preview output, but delete all skips them until you unsave them.
If GitHub metadata cannot be refreshed and there is no fresh cache, preview mode still shows other selected groups and prints a note that GitHub-backed metadata is unavailable.
Install
Once the crate is published, install it from crates.io with:
If you want the latest local source checkout instead:
Clone the repo, then install the binary with Cargo:
That places git-broom in Cargo's bin directory, typically ~/.cargo/bin.
If you prefer to build it without installing globally:
Running the tests
Core local checks:
Pre-commit hook
This repo includes a checked-in pre-commit hook at .githooks/pre-commit.
Enable it once per clone:
What it does:
- runs
rustfmton staged Rust files - automatically stages any formatting changes made by the hook
- runs
cargo clippy --all-targets --all-features -- -D warnings - fails the commit if linting fails
If you want to verify the same steps manually, run the commands in the previous section.
CI
GitHub Actions runs:
cargo fmt --all --checkcargo clippy --all-targets --all-features -- -D warningscargo test
Tests run on both Linux and macOS.
Releasing
This repo supports two release paths:
- first publish locally with
cargo publish --dry-run --lockedfollowed bycargo publish --locked - later tag-based releases through GitHub Actions by pushing a tag like
v0.1.1
The detailed maintainer workflow is documented in docs/releasing.md.
License
MIT. See LICENSE.