git delete-merged
17 Apr 2020I was pairing on a task and my colleague watched me repeatedly call the same git commands over and over in the terminal. I’d gotten into such a rhythm of calling the same sequence of commands that I hadn’t thought to codify it into one step. My colleague called me on it so now I’m writing a mini post in the hope it will force me to learn the lesson and share a helpful command.
The process I was repeating was for tidying up my local git repo when work had been merged on the remote. I was following a two step process of pruning remote branches and then removing local branches that have been merged.
The second part is more complex so let’s break that down first.
Removing local branches
We need to start by getting a list of branches that are merged:
➜ git branch --merged
bug/fix-text-encoding
feature/add-readme
master
* development
The output above shows that there are some branches that we probably don’t want to delete.
master
is our default branch so we want to keep that around and the branch marked with *
is our current branch, which we also want to keep.
We can protect these two branches by filtering our list:
➜ git branch --merged | egrep --invert-match "(\*|master)"
The grep here is inverted so it will only let lines through that do not match our regular expression.
In this case our regular expression matches the literal master
or any line starting with an asterisk.
The final thing to do with this filtered list is to delete these branches.
For this we pipe the output into git branch --delete --force
:
➜ git branch --merged | egrep --invert-match "(\*|master)" | xargs git branch --delete --force
Removing references to remote branches
This is much simpler and can be achieved with:
➜ git fetch --prune
Tying the two things together we get a final command of:
➜ git fetch --prune && git branch --merged | egrep --invert-match "(\*|master)" | xargs git branch --delete --force
Giving it a name
The above is quite a long command and although you can use your command line history to find it, we can do better.
I chose the name git delete-merged
for my command, which can be achieved by adding an alias to my global gitconfig
file:
➜ git config --global alias.delete-merged "\!sh -c 'git fetch --prune && git branch --merged | egrep --invert-match \"(\*|master)\" | xargs git branch --delete --force'"
With this in place I can now just call:
git delete-merged