Git Flow indeed is the one of the most popular Git Branching Model/ Strategy/Workflow in use today.
You can read more about Git Flow from the creator himself's post, "A successful Git branching model".
Git Flow is very helpful for quite matured projects (traditional) rather than the infant ones (fast-phased or continuous), IMHO. And for the matured ones, Git Flow has been proven to work very well.
The strategy's flow is a little slow-phased on the part of releasing branches (features) into master/production. And when a project hits a lot of feature tickets/requests the repository tends to clog up, local and remote. And when those branches are merged and closed from the origin, you will encounter the frustration of trying to remove those humongous number of merged branches from your local repository. And Git does not have, yet, the single command we want to delete all of those at the same time. Now, many of us searched the internet for answers, including myself, and got disappointed. 🙁
My answer? I created a script to do just that. 🙂
Steps how I came up with the Script
- Since
git
does not have a command to print us all the deleted branches, I tried to go backwards by printing all remote branches; and local branches, and then loop on the list of remote branches and delete them from the list of local branches.
To get the remote branches, use$ git branch -r --no-merged
This would print something like,
$ git branch -r --no-merged origin/feature/some-feature origin/feature/another-one
Now, I only want the branch name so I can easily strip my local branches list with it, and create a list (array) of it. I used this piped command.
IFS=" " read -r -a remoteBranches <<< $(git branch -r --no-merged | sed 's/\// /' | awk '{print $2;}' | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g')
- Create a list/array (space-delimited string) of local branches.
localBranches=$(git branch | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n / /g') # this command: sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' # strips all the newline and the 2 spaces before each line of the git branch result
- One by one strip the branches in
remoteBranches
from thelocalBranches
# loop and delete one by one deleted=$localBranches for branch in ${remoteBranches[@]}; do deleted=$(sed "s!${branch}!!" <<< ${deleted}) done
- And now delete the local branches. From what's left of your local branches list after stripping all branches from remote, those branches are already "not existing" on your remote.
git branch -dl ${deleted}
To sum it all up, here is the complete script:
#!/bin/bash prefix="feature/richmond/" # only delete my own branches if [ "$1" != "" ]; then prefix=$1 # or specify a prefix as argument fi currentBranch=$(git branch | grep "*" | awk '{print $2;}') git checkout master IFS=" " read -r -a branches <<< $(git branch -r --no-merged | grep ${prefix} | sed 's/\// /' | awk '{print $2;}' | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g') # get all existing branches in remote localBranches=$(git branch | grep ${prefix} | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n / /g') # get all local branches deleted=$localBranches for branch in ${branches[@]}; do # loop and delete one by one deleted=$(sed "s!${branch}!!" <<< ${deleted}) done if [ "$deleted" == "" ]; then echo "Nothing to delete, you local is clean." else git branch -dl ${deleted} fi git checkout $currentBranch # checkout where you last checked out
Or you can also checkout the Gist i created.
I added a prefix as I only want my branches to be deleted from my local.
This script is working with git version ~1.7