Clean up local git branches that no longer exist on remote - interactively and safely.
git fetch --prune only removes remote-tracking references (the refs in .git/refs/remotes/), but does NOT delete your local branches.
After merging PRs and deleting branches on GitHub/GitLab, you'll still have those local branches cluttering your git branch output. git-prune automates cleaning up those actual local branches.
# After someone merges and deletes your PR branch on GitHub:
git fetch --prune
# ✅ Removes refs/remotes/origin/feature/old-work
# ❌ Local branch feature/old-work still exists
git-prune
# ✅ Deletes the local feature/old-work branchRecommended setup:
# Automatic remote ref cleanup
git config --global fetch.prune true
# Manual local branch cleanup (run occasionally)
git-prune- 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
go install github.com/felixtorres/git-prune@latestRequirements: Go 1.16 or later must be installed.
git clone https://github.com/felixtorres/git-prune.git
cd git-prune
go build -o git-prune
sudo mv git-prune /usr/local/bin/Download the latest release from the releases page.
# 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# 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| 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 | - |
The following branches are never deleted:
mainmasterdevelopstagingproduction- Current branch (automatically detected)
- Any branch specified with
--keep
git-prune includes built-in tab completion for bash, zsh, fish, and powershell.
# One-time setup
git-prune completion bash > /etc/bash_completion.d/git-prune
# Or add to ~/.bashrc
source <(git-prune completion bash)# Add to ~/.zshrc
source <(git-prune completion zsh)
# Or for oh-my-zsh
git-prune completion zsh > ~/.oh-my-zsh/completions/_git-prunegit-prune completion fish > ~/.config/fish/completions/git-prune.fishgit-prune completion powershell | Out-String | Invoke-ExpressionAfter setup, you can use tab completion:
git-prune --<TAB> # Shows all available flags
git-prune --dry-<TAB> # Completes to --dry-run$ 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# 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# If you have upstream and origin remotes
git-prune --remote upstream
# Check specific remote
git-prune --remote origin --dry-run# Protect branches you're still working on
git-prune --keep feature-wip --keep experimental-ui- Fetches remote information - Runs
git fetch --pruneto update remote-tracking branches - Identifies local branches - Lists all local branches
- Categorizes branches:
- Protected: Default protected branches + current branch +
--keepbranches - Active: Branches that exist on the remote
- Stale: Branches that don't exist on the remote (candidates for deletion)
- Protected: Default protected branches + current branch +
- Optional filtering: If
--merged-onlyis used, only delete stale branches that have been merged - Confirmation: Prompts for confirmation unless
--forceis used - Deletion: Removes stale branches using
git branch -D
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
Make sure you're running the command from within a git repository:
cd /path/to/your/repo
git-pruneCheck your internet connection and remote configuration:
git remote -v
git fetch --allCheck if it's protected:
git-prune --dry-run
# Look at the "Protected branches" listMake sure $GOPATH/bin or $HOME/go/bin is in your PATH:
# Add to ~/.bashrc or ~/.zshrc
export PATH="$PATH:$HOME/go/bin"git clone https://github.com/felixtorres/git-prune.git
cd git-prune
go build -o git-prunego test ./...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
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details
Felix Torres (@felixtorres)
- Built with Cobra for CLI framework
- Terminal styling via Lipgloss
- Interactive prompts via Bubble Tea