Three Ways to Clean Up Local Git Branches
· 3 min readengineering #git #developer-productivity #workflow
Local branches build up quickly. You create one for a feature, a bug fix, or a quick experiment, then move on after the pull request is merged. Sometimes the remote branch gets deleted, the work already landed in main or another branch, or you're on a branch whose remote counterpart is long gone but the branch is still useful locally.
These commands cover those different cases.
Remove branches deleted from the remote
I use this as a starting point, but I preview the branches before deleting them.
Git Bash
git fetch -p && for branch in $(git branch -vv | grep ': gone]' | awk '{print $1}'); do git branch -D $branch; done
PowerShell
git fetch -p; git branch -vv | Select-String ': gone\]' | ForEach-Object { ($_ -split '\s+')[1] } | ForEach-Object { git branch -D $_ }
Use it after merged pull requests have their remote branches deleted. git fetch -p removes stale remote-tracking references. The rest force-deletes local branches whose upstream is gone.
It does not delete anything on the remote or touch branches without an upstream.
-D skips Git's unmerged-work check, so it deletes even branches with commits that never made it anywhere else. There's no preview step: it deletes as soon as it finds a gone-upstream branch. If you want to review a branch before it's removed, run git branch -vv | grep ': gone]' first and delete individually with -d.
Remove branches already merged into main
A remote branch can still exist after its work has landed in main. In that case, clean up by merge status.
Git Bash
git branch --merged main --format='%(refname:short)' | grep -vxE 'main|master|develop' | xargs -r -n1 git branch -d
PowerShell
git branch --merged main --format='%(refname:short)' | Where-Object { $_ -notin 'main', 'master', 'develop' } | ForEach-Object { git branch -d $_ }
Use this when your team keeps remote branches after merging, or when you only want to remove work that is already in main.
Replace main with your actual integration branch. These commands use -d, so Git keeps branches with unmerged commits.
Delete every local branch except main
Use this only when you do not need to keep local feature branches. For example, after finishing a batch of work or before starting fresh in a repository where you can recover branches from the remote.
Git Bash
git switch main && git branch --format='%(refname:short)' | grep -vxE 'main|develop' | xargs -r git branch -D
PowerShell
git switch main; if ($LASTEXITCODE -eq 0) { git branch --format='%(refname:short)' | Where-Object { $_ -notin 'main', 'develop' } | ForEach-Object { git branch -D $_ } }
This deletes every local branch except main and develop, whether it was merged or still has a remote branch.
Change main and develop to the branches you need to keep. Do not run it if local-only work might matter.