Git: Remove Merged or Gone Local Branches

Clean up local Git branches – delete merged branches, prune remotes, remove branches whose remote is gone, and set an alias to do it in one command.

git version control

Last updated: July 2026

After a few months of PRs, git branch scrolls forever. Three cleanup levels, from cautious to automated.

1. Delete branches already merged

git checkout main
git branch --merged

Everything listed (except your current branch) is fully contained in main — safe to delete:

git branch --merged | grep -vE '^\*|main|master|develop' | xargs -r git branch -d

The grep -vE guard protects long-lived branches; -d (lowercase) refuses anything not actually merged, so this command can’t lose work.

2. Prune deleted remote branches

When branches are deleted on GitHub/GitLab after merge, your local copy still remembers origin/feature-x:

git fetch --prune

Make pruning automatic on every fetch/pull:

git config --global fetch.prune true

3. Delete local branches whose remote is gone

Squash-merged branches never show as “merged” locally, so method 1 misses them. But after pruning, git marks their upstream as gone:

git branch -vv
#  feature-login  a1b2c3d [origin/feature-login: gone] add login page

Delete all of those in one line:

git branch -vv | awk '/: gone]/ {print $1}' | xargs -r git branch -D

Note the capital -D — required because squash-merged branches look unmerged to git. That also means this command would delete a genuinely unfinished branch whose remote was removed, so glance at the git branch -vv output first.

Put it behind an alias

git config --global alias.cleanup '!git fetch --prune && git branch -vv | awk "/: gone]/ {print \$1}" | xargs -r git branch -D'

Now git cleanup prunes and deletes in one step.

If you delete the wrong branch

The commits survive for weeks in the reflog:

git reflog                     # find the tip commit of the deleted branch
git branch feature-x a1b2c3d   # resurrect it

Which is the real reason branch cleanup is safe to automate: in git, deleting a branch only deletes the label, not the history.

Comments

comments