Extending Git with a Custom Command

Table of contents

The DreamFactory development team leans heavily upon Git and GitHub for repository management. Whether it's DreamFactory Genie, the DreamFactory website, the Getting Started with DreamFactory guide, or the platform itself, you can guarantee the code is managed within a repository. Apparently my own Git usage is such that it dominates my terminal command history, accounting for 32.689% of all commands executed (per the command zsh_stats )! Yet no matter how deep your Git expertise may be, eventually you'll have to combine commands with shell syntax in order to achieve more complicated tasks. One such example is deleting all locally merged branches. In this tutorial you'll learn how to do so by extending Git with a custom command.

Viewing Merged Branches

When working on a repository over a long period of time, it's easy for a number of previously merged local branches to accumulate. You can view this list by running the following command within one of your own repositories:

$ git branch --merged<br>accept-tos<br>master<br>new-registration-form<br>webhook-fix<br><br>

Deleting a Merged Branch

You can delete one of these branches using the following command:

$ git branch -d webhook-fix

But what if you wanted to delete all of the merged branches at once? According to this Stack Overflow post, it is possible but requires a bit of script-fu:

$ git branch --merged | egrep -v "(^*|master|dev)" | xargs git branch -d

Note the piped egrep command is ensuring the master and dev branches are filtered out of the results before they are passed to git branch -d. Therefore should you want to forego deleting other branches in addition to master and dev, you'll want to add them to the filter list.

Creating a Git Alias

Indeed, this command works perfectly, exactly as desired. But I'm never going to remember it. For such lengthy commands, it's commonplace to add them as aliases to your shell configuration file (~/.bashrc for Bash users, ~/.zshrc for Z shell users):

alias git-delete-merged="git branch --merged | egrep -v "(^*|master|dev)" | xargs git branch -d"

After adding this alias, you can reload the configuration file using the source command:

$ source ~/.zshrc

Extending Git with a Custom Command

While I guess this is a satisfactory improvement, it left me wanting. What about extending Git to include a delete-merged command? This way we could delete local merged branches using the following command:

$ git delete-merged

Yes! It turns out this is far easier than anticipated. Git will automatically extend itself with any executable shell script placed on the system path and assigned a name with a git- prefix. Therefore to add the above delete-merged command, all your have to do is add the following shell script to your path:

#!/bin/zsh<br>set -e<br>git branch --merged| egrep -v "(^*|master)" | xargs git branch -d

With the script done, save it with the file name git-delete-merged and then make sure it is executable:

$ chmod u+x git-delete-merged

Next, navigate to one of the project repositories and confirm it is visible on your path:

$ which git-delete-merged<br>/Users/wjgilmore/bin/git-delete-merged

With the new extension in place, I'm able to delete all local merged branches with the desired command:

$ git delete-merged<br>Deleted branch accept-tos (was a4798c4)<br>Deleted branch new-registration-form (was c38787b8)<br>Deleted webhook-fix (was d65433a3)

Thanks to this capability, the sky really is the limit in terms of how you can extend Git to do your bidding!