DEV Community

BotHot
BotHot

Posted on AI-assisted

How to clean up merged git branches safely (and the squash-merge trap)

If you work on a few repos for a year, your local branch list turns into a graveyard: feature/login-fix, tmp-test, hotfix-2, and fifteen more nobody remembers. Cleaning up is easy, but only if you avoid the commands that delete work by accident.

1. See what is already merged

git switch main
git pull
git branch --merged main
Enter fullscreen mode Exit fullscreen mode

Everything in this list has its commits in main already. Deleting these branches loses nothing. Ignore main itself and any branch you are currently on.

2. Delete with the safe flag

git branch -d old-feature
Enter fullscreen mode Exit fullscreen mode

The lowercase -d refuses to delete a branch that is not fully merged. The uppercase -D deletes regardless. Use -d by default and only reach for -D when you have looked at the branch and know you do not need it.

3. Delete many at once, with a preview

git branch --merged main | grep -vE '^\*|main|develop' > to-delete.txt
cat to-delete.txt          # read it first
xargs git branch -d < to-delete.txt
Enter fullscreen mode Exit fullscreen mode

Adjust the grep -v pattern to keep your protected branches. The text file is the preview: nothing is deleted until you have read it.

4. The squash-merge trap

If your team squash-merges pull requests, git branch --merged will not list those branches, because the squashed commit is a new commit. Git cannot tell they are merged. Check the pull request page instead, and only then delete with -D.

5. Remote branches

git fetch --prune
git branch -r --merged origin/main
Enter fullscreen mode Exit fullscreen mode

--prune removes local references to branches that were already deleted on the remote. Deleting remote branches (git push origin --delete name) affects your whole team, so ask first.

6. A habit that avoids most of this

Delete the branch right after the pull request is merged. Most hosting platforms have a setting to do that automatically.

If you do this often

I got tired of repeating these steps across repos and wrote a small Python tool that previews the list and then deletes the merged branches. It is mine and it is paid (9 EUR): https://skeilster.gumroad.com/l/uvpwln. Everything above works without it.

Which edge cases cause you trouble: squash merges, protected branches, something else?

Top comments (0)