One of the side-effects of using git branching aggressively is that you end up with a lot of branches in both the local and remote repositories.
For cleaning up branches on remote git repositories I use git-sweep. To remove local branches tied to remote branches that no longer exists I run git fetch --prune. This helps a lot but it doesn't handle the issue of local branch proliferation.
git branch --contains mybranch will list the branches that contain the commits of mybranch, i.e., the branches that mybranch has been merged into. If a branch has been merged into many branches it is a good candidate for cleanup.
To get a count of the number of branches all local branches have been merged into:
for k in $(git branch | tr -d "*");do git branch --contains "$k" | wc -l | tr -d '\n\t '; echo " $k" ;done | sort -nTo delete all local branches with more than MIN_COUNT branches they are merged into, including the branch you are currently on (typically master or your long-running development branch, e.g., dev):
MIN_CONTAINS=2
for k in $(git branch | tr -d "*");do [ $MIN_CONTAINS -lt $(git branch --contains "$k" | wc -l | tr -d '\n\t ') ] && git branch -d $k; done | sortThe reason why I don't like to run git branch -d on all local branches is that it would remove the merged feature branches I've recently worked on where I may have to add new commits in the near term. Focusing on the merge count leaves most "fresh" branches alone but tends to reliably get rid of stale branches whose commits have been merged.
At the end of it all, I take out the trash with git gc.