How to Clean Up Fully Merged Feature Branches
Table of Contents
Any Git repository may have several outdated branches lingering around. You realize it may be a good idea to clean up your project, but you're not sure which feature branches can be safely removed. Now what?
No worries — you've come to the right place. Let's find out how to delete fully merged branches from a Git repository with confidence.
Most projects have a designated base branch where all feature branches eventually get merged into, such as main
or master
. Depending on the workflow you are using, there may be more long-running branches; for example, some projects also have a next
branch, where the next release is prepared.
Base branches play an important role in determining if branches have been merged, because Git can only tell you that a branch has been merged into some other branch — it cannot determine if a branch has been merged in a way that it can be deleted.
For example, a branch could have been merged into next
but not into main
yet. How can you be sure?
Introducing git branch --contains
and git branch --merged
Git provides two helpers:
git branch --contains <commit>
git branch --merged <commit>
By typing git branch --contains <commit>
you will get the list of branches that contain the named commit. Your local list of branches will be filtered by the branches who are a descendant of a certain branch (or arbitrary commit). You could type git branch --no-contains <commit>
to get the opposite list.
In other words, the given branch has been merged into the listed branches. This would help you in determining if a branch has been merged into next
and main
.
With git branch --merged <commit>
, your local list of branches will be filtered by all the branches who have been merged into a given branch or commit. Similar to above, you could type git branch --no-merged <commit>
and only the branches not merged into the named commit would be listed.
This would help you get a list of branches that have been merged into next
. To see which branches have also been merged into main
, you would need to run the command again.
To put it another way, contains
and merged
are like a relationship and its inverse:
Note that these commands will only work with your existing local branches. Git doesn't magically detect which branches have been merged into e.g. next
for all history backwards — it simply checks your local branches one by one.
However, you can use the -r
option to run the checks against remote branches.
Pitfalls
There is a caveat: this only works if you merged branches through a plain git merge
. If you squash-merged a feature branch, cherry-picked a small feature branch, or somehow altered the commit hash, Git won't be able to detect if a given branch has been fully merged!
As an alternative, you check each branch individually with git cherry -v
, which will compare by diffs instead of hashes. Unfortunately, this isn't foolproof either; if you split up commits, for example, it won't be helpful.
This command requires a specific base branch to be given for comparison of a feature branch.
Let's find out how this can be simplified with Tower, our Git GUI for macOS and Windows.
We make Tower, the best Git client.
Not a Tower user yet?
Download our 30-day free trial and experience a better way to work with Git!
Cleaning Up Merged Branches In Tower
Based on the explanation above, filtering or answering the “Fully merged?” question is more effective if the user specifies a set of base branches that can be compared against.
For this reason, we introduced a new "Branches Review" view in Tower 8 for Mac.
This view compares your local branches to a base branch. You can filter this list of branches by "Fully Merged" to figure out the ones that can safely be deleted:
As you can see, with Tower, a cleaner repository is only a few clicks away!
This is only one of the several advanced features you can find in Tower. Don't forget that you can try it for free for 30 days!