Git - Delete your local branches

Rajat Kumar

Rajat Kumar

Engineer @ Netflix

With any long running git project, comes a bunch of stale and unused git branches. List of such unused old and stale branches builds up really quickly.

The more you experiment, more the number of stale branches, some get merged, some are just throw aways.

So, how can we clean up all the old local git branches? I struggled with this and so I decided to write about it!

This post covers the following:

Count the local branches

A simple way to count all your local branches under a git repo, just run the following command:

git branch | wc -l

When I ran this for one of my projects, I had 187 branches! In reality the project only had 5 active branches.

Prune remote branches

Prune remote branches?

Yes, think about all the branches that have already been removed from the remote repository. Your local copy might still have references to those branches.

You can prune your remote branches by running:

git remote prune origin

Start deleting local stale branches

First, lets find out all the local branches. I use :

git branch -vv

The -vv argument allows you to see what the last commits were on those branches.

For example on my machine it showed up something like:

add_cycle_detect c038087 [origin/add_cycle_detect: gone] fix: improve
coverage
develop e3d89a6 [origin/develop] Update mkdocs.yml
exclude_loader 8dff458 [origin/exclude_loader: gone] fix: spelling!
feat_logging 2cb1f62 fix: add version, namespace as required options
fix_less 04ff463 [origin/fix_less: gone] fix: change the node.value
structure
fix_vinea fd3aa98 [origin/fix_vinea: gone] fix: merge issue
master ca10358 [origin/master] chore: creating repo
wip-rajat b074d1e [origin/wip-rajat: gone] fix: changed test to work
with jest

The interesting text in this output is the fact that it shows local branches that do not have corresponding branches in remote. It is marked with the text : gone.

Example:

fix_less 04ff463 [origin/fix_less: gone] fix: change the node.value
structure
fix_vinea fd3aa98 [origin/fix_vinea: gone] fix: merge issue

All we want to do is to delete these branches.

Before we delete, these gone branches, lets try to list them:

git branch -vv | grep 'origin/.*: gone]'

This will show the branches that have been removed from origin:

add_cycle_detect c038087 [origin/add_cycle_detect: gone] fix: improve
coverage
exclude_loader 8dff458 [origin/exclude_loader: gone] fix: spelling!
fix_less 04ff463 [origin/fix_less: gone] fix: change the node.value
structure
fix_vinea fd3aa98 [origin/fix_vinea: gone] fix: merge issue
wip-rajat b074d1e [origin/wip-rajat: gone] fix: changed test to work
with jest

Next, we need to extract the branch names, which happens to be the 1st word in each line and then pass these names to git to delete.

So, extract the 1st word in each line by using awk '{print $1}' and then pass it to git branch -d using xargs.

The final command should look like:

git branch -vv | grep 'origin/.*: gone]' | awk '{print $1}' | xargs git branch -d

Bonus: Deleting any local branch

The ONE thing you should understand is that actual action of deleting the branch happens when we run:

git branch -d <branch_name>

For example, if you wish to remove the branch fix_less from your local, just run:

git branch -d fix_less

Deleting with -d vs -D

-d is Delete

This deletes the local branch only when all the changes are pushed/merged/committed.

-D is Force Delete

This deletes the local branch irrespective of push and merge status. You might lose your work!

Bonus: Deleting the remote branch

To delete a remote branch, just run:

git push <remote_name> --delete <branch_name>

For example, if you wish to remove the branch fix_less from origin, just run:

git push origin --delete fix_less