All Articles

Git - Delete your local branches

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!

1. 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.

2. 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

3. 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