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!

Table of Content


1. Count the local branches

git branch | wc -l

A simple way to count all your local branches under a git repo, just run this command.

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.

git remote prune origin

You can prune your remote branches by running this command.

3. Start deleting local stale branches

First, lets find out all the local branches.

git branch -vv

You can run this command to find out all the local branches.

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

For my project, execution of this command showed up the list of branches with last commit.

fix_less 04ff463 [origin/fix_less: gone] fix: change the node.value structure
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
fix_less 04ff463 [origin/fix_less: gone] fix: change the node.value structure
feat_logging 2cb1f62 fix: add version, namespace as required options

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

These branches are marked with the text


gone

All we want to do is to delete these branches marked with gone 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.

Running this against my project listed out these branches which did not have any corresponding branch in remote.

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.

The way I do it looks like this:

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

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

Bonus: Deleting any local branch

git branch -d fix_less
git branch -d <branch_name>
git branch -d fix_less

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

Example: if you wish to remove the branch fix_less from your local, your command would look like this.

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

git push origin --delete fix_less
git push <remote_name> --delete <branch_name>
git push origin --delete fix_less

To delete a remote branch, we can use this.

For example, if you wish to remove the branch fix_less from remote origin, just run this.

Conclusion

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

This is my way of removing all my local branches which do not have corresponding branch in the remote origin.

That’s it for now. I hope you liked it.

Thanks for reading!