Delete local Git branches after deleting them on the remote repo
The quick way
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
NB: if you're not on master
, this has the potential to delete the branch. Keep reading for the "better way".
Make sure we keep master
You can ensure that master
, or any other branch for that matter, doesn't get removed by grep
ing for more. In that case you would go:
git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d
So if we wanted to keep master
, develop
and staging
for instance, we would go:
git branch --merged | grep -v "\*" | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d
Make this an alias
Since it's a bit long, you might want to add an alias to your .zshrc
or .bashrc
. Mine is called gbpurge
(for git branches purge
):
alias gbpurge='git branch --merged | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d'
Then reload your .bashrc
or .zshrc
:
. ~/.bashrc
or
. ~/.zshrc
This should work to avoid deleting the master and development branches with the accepted solution:
git branch --merged | egrep -v "^\*|master|development" | xargs -n 1 git branch -d
I use the same flow with GitHub, and didn't find the previous answers satisfying me, as git branch --merged
lists branches which were merged, but not every of them was removed remotely in my case.
So, this worked for me:
git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
where:
git fetch --all -p
: update local branches statusgit branch -vv
: list local branches statusgrep ": gone]"
: filter deleted onesawk '{ print $1 }'
: extract their namesxargs -n 1 git branch -d
: pass the name to the delete command
Note: if you prefer, you could use -D instead of -d, which enforces the delete.
For example:
someUsr@someHost:~/repo$ git branch -a
basic-testing
integration-for-tests
* master
origin
playground-for-tests
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services
someUsr@someHost:~/repo$ git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
Fetching origin
Deleted branch integration-for-tests (was fbc609a).
Deleted branch playground-for-tests (was 584b900).
someUsr@someHost:~/repo$ git branch -a
basic-testing
* master
origin
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services
Reference:
http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches
try:
git pull --prune
which deletes your local branch, if its corresponding remote branch is deleted.
Updated:
The statement above is not that correct.
In fact, running git pull --prune
will only REMOVE the remote-tracking branches such like
remotes/origin/fff remotes/origin/dev remotes/origin/master
Then, you can run git branch -r
to check the remote-tracking branches left on your machine. Suppose the left branches are:
origin/dev origin/master
which means the branch origin/fff
is deleted.
So, after running git pull --prune
, just run:
git branch --merged | grep -vFf <(git branch -r | cut -d'/' -f2-)
you can find out all the local branches which:
- have no correspoding remote branches any more;
- can be removed safely.
then, <the command above> | xargs git branch -d
can delete all of them.