Safely reap merged & gone-upstream git branches — clean up your local branch clutter in one pass. Zero dependencies, no install.
Project description
branchreap
Safely reap merged & gone-upstream git branches. After a few months, git branch becomes a graveyard: dozens of feature/* that shipped long ago, and
tracking branches whose remote was deleted the moment the PR merged.
branchreap finds the ones that are actually safe to delete — and only those.
Zero dependencies, pure standard library.
# Run without installing:
pipx run branchreap # scan (read-only)
# Or install it:
pip install branchreap
branchreap clean # reap, with a confirmation prompt
What it reaps
- Merged branches — local branches fully merged into your default branch.
- Gone branches — tracking branches whose upstream was deleted (
[gone]), as long as they carry no unmerged work.
What it will never touch
- the current branch
- the default branch (
main/master/ whateverorigin/HEADpoints at) - unmerged or unpushed work, or any branch with commits of its own —
unless you explicitly pass
--include-unmerged(and even then, never the current or default branch)
That safety floor is the whole point: run it without reading the docs and the
worst case is it deletes a branch git itself considers fully merged.
Why not git branch --merged | xargs git branch -d?
Because that one-liner misses gone-upstream branches, happily lists main, and
does nothing about the "is this actually safe?" question. branchreap does
merged and gone in one pass, protects the branches you'd regret losing, and
runs instantly with pipx (or npx — there's a byte-for-byte twin on npm), no
toolchain to install.
Usage
branchreap # scan (read-only, default)
branchreap scan --json # machine-readable
branchreap clean --dry-run # preview exactly what would be deleted
branchreap clean # delete, with a confirmation prompt
branchreap clean --yes # delete, no prompt (scripts / aliases)
Options
--main <branch> Override the detected default branch
--fetch Run 'git fetch --prune' first, so 'gone' status is fresh
--include-unmerged Also reap gone branches with unmerged commits (uses -D)
--json Machine-readable scan output
-y, --yes Skip the confirmation prompt
--dry-run Show what would be deleted, delete nothing
Example
$ branchreap
default branch: main
✗ feature/old-login merged merged into main
✗ fix/typo gone upstream gone · merged into main
────────────────────────────────────────────────────────
2 reapable (1 merged · 1 gone) · 4 kept
1 gone branch(es) held back (unmerged commits). Use --include-unmerged to reap.
Exit codes
| Code | Meaning |
|---|---|
0 |
ok |
2 |
error (not a git repo, bad args, or a deletion failed) |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file branchreap-0.1.0.tar.gz.
File metadata
- Download URL: branchreap-0.1.0.tar.gz
- Upload date:
- Size: 10.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed9184b1961043776d2db0edfa467369ab98bb5d02277dc5badfda001127d43a
|
|
| MD5 |
ecb1a5ff9d68caa8042314bf8f04d90b
|
|
| BLAKE2b-256 |
d0bfdef07ad630b596c4dddbf6643a162eb1538cbeb7f3c61158e6a0b9d4e8e7
|
File details
Details for the file branchreap-0.1.0-py3-none-any.whl.
File metadata
- Download URL: branchreap-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b420e89d2e0a092485ba1167f8b0590ac7198e97ce1fd1243cdaff7c9a4e3a30
|
|
| MD5 |
031264b30fea30a4289cae1e070fff4b
|
|
| BLAKE2b-256 |
ae3c1a6fbfd7944be535b378982d6ad568db557945cc1ec4a8130d283e661738
|