Cleanup and remove all merged local and remote git branches

April 1, 2015

After working on a project for a while you wind up with lots of feature and hotfix branches. If you are working on a team with a remote cannonical project repo there will likely be dozens or hundreds of stale branches that need pruning. Here are a few quick commands that will help you clean up your branches.

TL;DR – Just give me the code!

Get a list of remote branches

[bash]for remote in `git branch -r `; do git branch –track $remote; done[/bash]

Remove remote branches

[bash]git branch –merged master | grep -v master | cut -d/ -f2- | xargs -n 1 git push –delete origin[/bash]

Remove local branches

[bash]git branch –merged master | grep -v master | xargs -n 1 git branch -d[/bash]

Order is important

The order that you remove branches in is important. You must remove the remote branches first otherwise git will not know how to reference the names of the remote branches and they will remain.

Get a list of branches

Chances are if you are working with a team you will not have all of the remote repo branches locally. In order to remove the remote branches your local git needs to know about them. This command will pull a list of the remote branches without fully checking them out. You do not need the contents of the branch, only the name for reference.

[bash]for remote in `git branch -r `; do git branch –track $remote; done[/bash]

Note: While writing this I realized there may be a more efficient way to do this by passing the branch name directly into git’s delete function. I will test this in the future on another cleanup.

Remove merged remote branches

Remote branches that have been merged into master should generally be safe to remove and can easily be accomplished via:

[bash]git branch –merged master | grep -v master | cut -d/ -f2- | xargs -n 1 git push –delete origin[/bash]

Per command breakdown

Get a list of all branches that have been merged into the master branch:

[bash]git branch –merged master[/bash]

Just to be safe cut out the master branch from the previous output if it exists:

[bash]grep -v master[/bash]

When you ran the command to pull a list of remote branches without checking them out is probably added ‘origin/‘ into the branch name. This will confuse the remote repo during the delete operation. The following removes origin/ from the branch name before passing it to the delete command:

[bash]cut -d/ -f2-[/bash]

Finally you can call the git command to delete the remote branch. The xargs command passes the branch names with their manipulations to the git command:

[bash]xargs -n 1 git push –delete origin[/bash]

Remove merged local branches

Local branches that have been merged into master should generally be safe to remove and can easily be accomplished via:

[bash]git branch –merged master | grep -v master | xargs -n 1 git branch -d[/bash]

Per command breakdown

Get a list of all branches that have been merged into the master branch:

[bash]git branch –merged master[/bash]

Just to be safe cut out the master branch from the previous output if it exists:

[bash]grep -v master[/bash]

Finally you can call the git command to delete the remote branch. The xargs command passes the branch names with their manipulations to the git command:

[bash]xargs -n 1 git branch -d[/bash]

4 thoughts on “Cleanup and remove all merged local and remote git branches

  1. jirisvejda (September 16, 2015)

    Thanks! Works great.

  2. Vaclav Kosar (June 18, 2016)

    We use git-obsolete-branch-remover useful as it lists or removes local or remote Git branches based on last commit date and merge status.
    https://github.com/vackosar/git-obsolete-branch-remover

    1. Ben Lobaugh (blobaugh) (June 24, 2016)

      This is a nifty looking tool, however I do not think it fits my current scenario too well. It looks like this tool requires you to pass it a number of days before something is considered obsolete. On the projects I am working with the branches may be around for a while before being merged into the production branch. Thus time does not matter and the only metric I have to go on is merge status with the production branch.

  3. J (October 27, 2016)

    I implemented this, but it appears to remove branches which have been merged, but then later modified, and not remerged – this results in potentially new and unique code being deleted.

    Can you think of a way to modify this which would result in unique remote branches which have been previously merged being spared?

    Thanks,
    J