Short version:
Use this command:
1 | git fetch -p && for branch in $(git for-each-ref --format '%(refname) %(upstream:track)' refs/heads | awk '$2 == "[gone]" {sub("refs/heads/", "", $1); print $1}'); do git branch -D $branch; done |
Original answer:
After the command
1 | git fetch -p |
removes the remote references, when you run
1 | git branch -vv |
it will show ‘gone’ as the remote status. For example,
1 2 3 4 5 6 | $ git branch -vv master b900de9 [origin/master: behind 4] Fixed bug release/v3.8 fdd2f4e [origin/release/v3.8: behind 2] Fixed bug release/v3.9 0d680d0 [origin/release/v3.9: behind 2] Updated comments bug/1234 57379e4 [origin/bug/1234: gone] Fixed bug |
So you can write a simple script to remove local branches that have gone remotes:
1 2 | git fetch -p && for branch in $(git branch -vv | grep ': gone]' | awk '{print $1}'); do git branch -D $branch; done |
Note that the above uses the “porcelain” command git branch
to get the upstream status.
Another way to obtain this status is to use the “plumbing” command git for-each-ref
with the interpolation variable %(upstream:track)
, which will be [gone]
just like above.
This approach is somewhat safer, because there is no risk of accidentally matching on part of the commit message.
1 | git fetch -p && for branch in $(git for-each-ref --format '%(refname) %(upstream:track)' refs/heads | awk '$2 == "[gone]" {sub("refs/heads/", "", $1); print $1}'); do git branch -D $branch; done |