git-prune
A professional CLI tool to remove stale local git branches that no longer exist on the remote repository.
Features
- Remove local branches deleted from remote
- Interactive confirmation prompts
- Colored terminal output
- Dry-run mode to preview changes
- Protected branches (never deleted)
- Tab completion for bash/zsh/fish/powershell
- Cross-platform support (macOS, Linux, Windows)
- Additional safety features:
--merged-only - Only delete branches merged to main
--remote - Specify which remote to check
--verbose - Show detailed git command output
Installation
Via go install (Recommended)
go install github.com/felixtorres/git-prune@latest
Requirements: Go 1.16 or later must be installed.
From Source
git clone https://github.com/felixtorres/git-prune.git
cd git-prune
go build -o git-prune
sudo mv git-prune /usr/local/bin/
Pre-built Binaries
Download the latest release from the releases page.
Usage
Basic Usage
# Preview what would be deleted (recommended first step)
git-prune --dry-run
# Delete stale branches with confirmation
git-prune
# Delete without confirmation
git-prune --force
Advanced Options
# Protect additional branches
git-prune --keep feature-important --keep hotfix-123
# Only delete branches merged to main
git-prune --merged-only
# Check against a specific remote
git-prune --remote upstream
# Show verbose git output
git-prune --verbose
# Combine options
git-prune --dry-run --merged-only --remote origin
All Options
| Flag |
Description |
Default |
--dry-run |
Show what would be deleted without deleting |
false |
--force |
Skip confirmation prompt |
false |
--keep <branch> |
Protect additional branch (repeatable) |
[] |
--remote <name> |
Specify remote to check against |
origin |
--merged-only |
Only delete merged branches |
false |
--target <branch> |
Target branch for merge check |
main/master |
--verbose, -v |
Show verbose git command output |
false |
--help, -h |
Show help message |
- |
--version |
Show version |
- |
Protected Branches
The following branches are never deleted:
main
master
develop
staging
production
- Current branch (automatically detected)
- Any branch specified with
--keep
Tab Completion
git-prune includes built-in tab completion for bash, zsh, fish, and powershell.
Bash
# One-time setup
git-prune completion bash > /etc/bash_completion.d/git-prune
# Or add to ~/.bashrc
source <(git-prune completion bash)
Zsh
# Add to ~/.zshrc
source <(git-prune completion zsh)
# Or for oh-my-zsh
git-prune completion zsh > ~/.oh-my-zsh/completions/_git-prune
Fish
git-prune completion fish > ~/.config/fish/completions/git-prune.fish
PowerShell
git-prune completion powershell | Out-String | Invoke-Expression
After setup, you can use tab completion:
git-prune --<TAB> # Shows all available flags
git-prune --dry-<TAB> # Completes to --dry-run
Examples
Example 1: First-time use
$ git-prune --dry-run
ℹ Git Branch Pruning Tool
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ Current branch: main
ℹ Protected branches (will not be deleted):
- main
- master
- develop
- staging
- production
ℹ Fetching remote information...
✓ Remote information updated
ℹ Analyzing local branches...
⚠ Found 3 stale branch(es) to delete:
✗ feature-old
✗ bugfix-123
✗ experiment
ℹ Summary:
- Protected branches: 5
- Active branches: 2
- Stale branches: 3
ℹ Dry run mode - no branches were deleted
ℹ To delete these branches, run without --dry-run flag
Example 2: Safe deletion (merged only)
# Only delete branches that have been merged to main
git-prune --merged-only
# This is safer as it won't delete branches with unmerged work
Example 3: Working with multiple remotes
# If you have upstream and origin remotes
git-prune --remote upstream
# Check specific remote
git-prune --remote origin --dry-run
Example 4: Protecting important branches
# Protect branches you're still working on
git-prune --keep feature-wip --keep experimental-ui
How It Works
- Fetches remote information - Runs
git fetch --prune to update remote-tracking branches
- Identifies local branches - Lists all local branches
- Categorizes branches:
- Protected: Default protected branches + current branch +
--keep branches
- Active: Branches that exist on the remote
- Stale: Branches that don't exist on the remote (candidates for deletion)
- Optional filtering: If
--merged-only is used, only delete stale branches that have been merged
- Confirmation: Prompts for confirmation unless
--force is used
- Deletion: Removes stale branches using
git branch -D
Why git-prune?
Advantages over bash scripts:
- Works anywhere (no copying files between machines)
- Tab completion for all flags
- Cross-platform (Linux, macOS, Windows)
- Easy updates via
go install
- Professional UX with colors and interactive prompts
- Additional safety features (merged-only, verbose mode)
Advantages over manual deletion:
- Batch operations (delete many branches at once)
- Safety checks (protected branches, dry-run mode)
- Consistent behavior across teams
- No mistakes from typos
Troubleshooting
Error: "Not a git repository"
Make sure you're running the command from within a git repository:
cd /path/to/your/repo
git-prune
Error: "Failed to fetch remote"
Check your internet connection and remote configuration:
git remote -v
git fetch --all
Branch isn't being deleted
Check if it's protected:
git-prune --dry-run
# Look at the "Protected branches" list
Command not found
Make sure $GOPATH/bin or $HOME/go/bin is in your PATH:
# Add to ~/.bashrc or ~/.zshrc
export PATH="$PATH:$HOME/go/bin"
Development
Building from source
git clone https://github.com/felixtorres/git-prune.git
cd git-prune
go build -o git-prune
Running tests
go test ./...
Project structure
git-prune/
├── main.go # CLI entry point
├── internal/
│ ├── git/git.go # Git operations
│ ├── prune/prune.go # Pruning logic
│ └── ui/ui.go # UI formatting
├── go.mod
├── go.sum
└── README.md
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details
Author
Felix Torres (@felixtorres)
Acknowledgments