Creating branches in git basically free and is easy to do. This has lead to the development of techniques like git flow and other branch related work streams, which are now commonplace in development.
If you have a project being worked on by many developers you can get into the situation where there are many branches in the project. Some will be merged, some will be worked on currently and some more will be branches that were worked on, but never finished (for one reason or another). This can lead to some confusion over what branches are being worked on, especially if you want an oversight on the current health of the project.
As an example, I once inherited a project from another agency that contained over 250 branches in the repo. Although the branches had a well structured naming scheme, it was difficult to tell what was being worked on and what was already merged. This situation was confusing as the job board we were looking at only had 5 active tickets being worked on. In order to proceed with the code I needed to clean up some of these branches.
Stale branches (merged or not) are, in my opinion, nothing short of technical debt. Let's say that a developer branched off to add a feature of fix a bug on a project. After doing some work and pushing their branch into the repo they then had to move onto another feature due to a change of priorities in the project. If that branch is still present 6 months later, merging that work into the project is so dangerous that it's almost certainly easier to just start again.
Finding Merged Branches
Perhaps the easiest decision to make was to delete branches that had been merged with the master branch. If a branch has been merged with the current work stream then it should be deleted, unless further work is being done on that branch.
To find the branches that have been merged with the branch you have currently checked out (i.e. HEAD) use the following--merged flag. Combined with the -r flag allows us to compare against the default remote.
git branch -r --merged
To find branches that have been merged with a specific remote branch (e.g. origin/master) use the following.
git branch -r --merged origin/master
You can do this against a develop branch if you like, but if the develop branch is merged with master then this will show the same information.
This will print out the list of branches. For example, this shows that the local two other branches have been merged with the master branch.
origin/master origin/develop origin/feature-1
This gives us a clear candidate for deletion, namely origin/feature-1. The decision should rely on how long ago the code was merged as a branch that was merged 6 months ago really doesn't need to be kept.
Finding Unmerged Branches
A slightly harder decision to make is whether to delete unmerged branches. Each branch needs to be checked out and inspected to see what has been changed and, more importantly why. The final decision depends on if the code can (or should) be merged with the upstream branches.
To find all unmerged branches use the --no-merged flag on the branch command. We are again using the -r flag to compare the remote.
The following will compare the current checked out branch (ie. HEAD) with the default remote.
git branch -r --no-merged
To find what branches have not been merged with a branch, specify it like this.
git branch -r --no-merged origin/master
This will again just print out a list of branches.
Once you have found the branches I recommend using a GUI tool to inspect the history of the branch and any commits made to it. Tools like Sourcetree and Git Kraken are good ways of doing this. It is possible to do this via the command line, but I find that it's easy to miss things this way.
Once you've made your decision it is then time to delete the branch.
Delete Remote Branches
To delete the local branch then use this command.
git branch -d feature-1
You can't use the branch command to delete remote branches. So to delete a remote branch just run the push command, specifying which branch should be deleted.
git push origin --delete feature-1