Git Prune: Remove Stale Remote-Tracking Branches Safely
Preview stale Git remote-tracking references before pruning, and learn when custom refspecs or tag settings need extra care.
A deleted branch can keep appearing in git branch -r long after it disappears from the server. Often the leftover name is a remote-tracking reference: your local repository's record of where a remote branch was last seen. Git does not automatically remove every stale reference when a branch is deleted remotely.
For an ordinary clone, preview the cleanup with git remote prune --dry-run origin, then use git remote prune origin if the listed references are ones you expect to disappear. With the usual branch mapping, this removes local tracking names; it does not delete branches on the server or your local working branches. If you also want to fetch updates, git fetch --prune origin combines a fetch with pruning.
There is an important exception: pruning follows the remote's configured refspecs, not a universal rule that only branch names can be removed. A custom refspec or tag-pruning setting can bring local tags into scope. Check the configuration and preview before proceeding, especially in a mirror or a repository with unusual fetch settings. The Git fetch manual explains this distinction.
Understand the three names
Suppose a teammate deletes feature/menu on the server. Your clone may still list origin/feature/menu under remote branches. That is a local record of the last observed remote state, not a live query of the server. A local branch named feature/menu, if you have one, is a separate reference. Your working files and any uncommitted changes are separate again.
With a normal clone's usual branch mapping, pruning removes the stale origin/feature/menu reference when the server no longer has the corresponding branch. It does not merge work or remove your local feature/menu branch. A local branch may then show its upstream as gone; that is a prompt to decide what to do with the local work, not a reason to delete it automatically.
Check the remote and its configuration
From the repository directory, first identify the remote and its current local tracking references:
git remote -v
git branch -r
git branch -vv origin is a common remote name, not a requirement. Substitute the name you intend to inspect. git branch -vv shows local branches and their upstream information; read it before deciding whether any local work needs attention. Remote URLs can contain credentials in some setups, so avoid sharing their output without checking it.
Inspect the configured fetch mappings and pruning settings:
git config --show-origin --get-all remote.origin.fetch
git config --show-origin --get-regexp '^(fetch|remote\.origin)\.prune(tags)?$' The typical clone mapping is +refs/heads/*:refs/remotes/origin/*: remote branches map to local origin/* tracking references. If the second command prints nothing and exits with a nonzero status, no matching setting was found; that alone is not a failure. If you see a tag mapping such as refs/tags/*:refs/tags/*, a mirror mapping, fetch.pruneTags, or remote.origin.pruneTags, stop and understand the configuration before pruning. Other explicit mappings can change the affected references too. The Git configuration reference describes these settings.
Preview, then prune
- Ask Git what it would remove with
git remote prune --dry-run origin. - Read every proposed deletion. If a name is unexpected, confirm the remote, inspect the refspecs and check with your team before continuing. The preview requires access to the remote; an authentication or network error is not a clean preview.
- If the list is expected, run
git remote prune origin. - Check
git branch -ragain. The stale references identified in the preview should be gone. Rungit branch -vvto see whether a local branch has lost its upstream.
The remote manual distinguishes this operation from git fetch --prune origin: remote prune removes stale references without fetching new ones, while fetch also retrieves updates. Either operation can be affected by the configured refspecs. A preview is a point-in-time check: if the remote changes between preview and cleanup, inspect again.
A small example
Imagine origin/feature/menu appears in git branch -r, while the team has already deleted feature/menu on the server. The dry run reports that origin/feature/menu would be pruned. After reviewing the mapping and running the prune command, the remote-tracking name disappears from git branch -r.
If your own local feature/menu still exists, it remains available. Inspect it with git log --oneline --decorate feature/menu and compare its history with the relevant branch before deciding whether to keep, merge or delete it. Pruning does not prove its commits are safely integrated. Do not run git branch -D merely to make the list look tidy.
Tags, automatic pruning and recovery
Git's ordinary automatic tag following does not by itself make tags subject to pruning. An explicit tag refspec or a prune-tags setting can change that, and a local tag absent from the remote can be removed. Tags may be shared across remotes, so review the configuration even when only one remote is being pruned. Do not add --prune-tags casually.
You can configure pruning for future fetches with git config remote.origin.prune true, but consider this only after understanding the repository's mappings. It changes future behavior for this repository; undo it with git config --unset remote.origin.prune. The fetch manual also documents a global setting, which affects other repositories and deserves a wider review.
If a tracking reference was pruned but the remote branch still exists or is recreated, a later normal fetch using the appropriate mapping can recreate it. If the branch was truly deleted remotely, fetching cannot bring it back from that server. A surviving local branch, another clone, or a known commit ID may help recover the work; preserve those references and coordinate with the team before attempting recovery. Pruning a name is not a backup strategy.
Subscribe
Get new articles by email. Unsubscribe with one click.