You deleted a branch on GitHub or GitLab, but when you type git checkout and hit Tab, the deleted branch still shows up in tab completion. This happens because Git keeps local references to remote branches even after they’re removed from the remote. Here’s how to clean them up.
The examples in this guide are run on WSL2 Ubuntu in Windows, but they work the same on any system with Git installed.
Why Deleted Branches Still Appear
When you run git fetch, Git creates remote tracking branches like origin/feature-login in your local repo. When someone deletes that branch on the remote, your local copy of origin/feature-login doesn’t get removed automatically. Git tab completion reads from these stale references.
You can see them with:
git branch -r
Branches that no longer exist on the remote will still be listed here.
Remove Stale Remote Branches
Option 1: Fetch and Prune
The quickest fix — fetch the latest changes and remove stale references in one command:
git fetch --prune
--prune— removes any remote tracking branches that no longer exist on the remote
After running this, try Tab completion again — the deleted branches should be gone.
Option 2: Prune a Specific Remote
If you only want to prune without fetching new data:
git remote prune origin
Preview what would be removed without actually deleting anything:
git remote prune origin --dry-run
Enable Auto-Prune
Instead of remembering to prune manually, tell Git to do it automatically on every fetch:
git config --global fetch.prune true
Now every git fetch and git pull will clean up stale remote branches automatically. This is the best approach — set it once and forget about it.
Clean Up Local Branches Too
Pruning only removes remote tracking references (origin/branch-name). If you also created local branches that have been merged and deleted on the remote, those local branches still exist.
See which local branches have lost their upstream (marked as gone):
git branch -vv | grep 'gone]'
Delete them one by one:
git branch -d branch-name
Or delete all merged local branches whose remote is gone, in one command:
git fetch --prune && git branch -vv | grep 'gone]' | awk '{print $1}' | xargs -r git branch -d
git branch -vv— lists local branches with their upstream tracking infogrep 'gone]'— filters to branches whose remote was deletedawk '{print $1}'— extracts just the branch namexargs -r git branch -d— deletes each branch;-donly deletes if fully merged (safe)
The -d flag is safe — it refuses to delete branches with unmerged changes. If you need to force-delete, use -D instead, but review the branches first.
Quick Reference
| Command | What it does |
|---|---|
git fetch --prune |
Fetches and removes stale remote tracking branches |
git remote prune origin |
Prunes stale references without fetching |
git remote prune origin --dry-run |
Shows what would be pruned (no changes) |
git config --global fetch.prune true |
Auto-prune on every fetch/pull |
git branch -r |
Lists all remote tracking branches |
git branch -vv |
Lists local branches with upstream status |
Conclusion
Run git fetch --prune to clear stale remote branches from tab completion, or set fetch.prune true globally so it happens automatically. For a full cleanup, also delete local branches whose remotes are gone.
For more Git workflow tips, check out How to Configure Git Pushes Without Authentication Prompts or Safety Moving Uncommitted Changes to A New Branch in Git.