Create custom git subcommands using shell script

A step-by-step guide on how to create custom git subcommands.

Create custom git subcommands using shell script

Photo by Yancy Min on Unsplash

Have you ever wanted the built-in git subcommands to do just a bit more? Say, storing extra information about some commits, generating some informatics, or taking care of housekeeping chores without resorting to a long headache-inducing string of git keywords?

A custom subcommand is what you are looking for. What is a git subcommand anyway? When we type in a git command like below in the terminal, “branch” is the subcommand here, and “new-branch” is the argument to that subcommand. Subcommands are what we use to interact with Git.

$> git branch new-branch

In this post, we will be looking into how git finds custom subcommands that can be run from any local git repository and how to create your very own subcommand. We will be creating a subcommand called custom-branch that will extend the behavior of the branch subcommand by checking out the given branch if it already exists or creating the given branch from its parent and storing this information as a record. 🎆

What do you need to know to follow along? If you know which one is the git client or the subcommand or option in the following code, you are good to go!

git checkout -b test-branch

(BTW, git is the client for Git, and checkout is the subcommand. Now you know, 😜)

First things first. How to tell Git to find and recognize custom subcommands that we can use in the same way as “git add” or “git branch”? Follow these three simple steps:

  1. The code for each custom subcommand needs to reside in its own file. What type of file? A simple file with no extension will suffice!

  2. The file name should follow a particular naming format, “git-” followed by the name of the custom subcommand. E.g. if the subcommand we are trying to create is called foo, then the file name will be “git-foo”, without any extension. In our case, the subcommand will be called custom-branch, so the file name will be “git-custom-branch”.

  3. The system PATH variable must contain the location of the directory that the custom subcommand file is in. E.g. if our “git-custom-branch” file is located in the folder “customgit/”, then the location of this directory must be included in the PATH environment variable.

Great job till now!!!

Now let’s follow these steps and create our “custom-branch” subcommand. So, what will this subcommand do? It will extend the functionality of the built-in subcommand “branch” by storing the parent branch name if a new branch is created, otherwise checking out the given branch.

  1. First, we create the folder that will contain the file of our custom subcommand. Open a terminal and type “cd ~”. This will take you to the HOME directory of the current user, which is you 😺.

  2. Now create a new folder called “customgit” by typing “mkdir customgit” and get into it by typing “cd customgit”.

  3. Next, create a file named “git-custom-branch”, either manually or using “touch git-custom-branch”. Give execute permission to the file using “chmod +x git-custom-branch”, otherwise Git won’t be able to execute the subcommand written in the file.

cd ~
mkdir customgit
cd customgit
touch git-custom-branch
chmod +x git-custom-branch

4. Then, add the following line to the respective shell configuration file. Make sure you run the command that is appropriate based on your OS. This command simply adds the directory path of our “customgit” folder to the environment PATH variable. After modifying the shell file, either open a new terminal for the changes to take effect or simply type “source ~/.bashrc” (“source ~/.zshrc” for MacOS users) in the current terminal.

# Mac users who use Z Shell
echo 'export PATH="$HOME/customgit:$PATH"' >> ~/.zshrc
# Linux or MacOS users who use Bash
echo 'export PATH="$HOME/customgit:$PATH"' >> ~/.bashrc

5. Now, open the “git-custom-branch” file in your favorite text editor and add the following blocks of code. The completed file can be found here.

#1 First, we add the “hashbang” to denote which interpreter should be used to execute this file, Bash.

#3–6 Next, we want our custom command, “git custom-branch …” to have an effect only if it is executed inside a Git repository. The following code block checks that, or exits otherwise.

#8, 9 Now that we know we are running the command in a Git repository, we retrieve the currently checked-out branch that will be used later as the parent branch while creating the new branch, unless the user provides a parent branch of their own.

Now, the big boi! 😉

#11 We first check if the new branch name is provided as the first command-line argument to our custom git command, “git custom-branch test-branch”. Here $1 would be test-branch.

#33 Otherwise, we exit the program!

#13 Here, we check if there is already a branch with the given name. If it exists, we simply check out that branch.

#18 Otherwise, we check if the user has provided their own parent branch as the second command-line argument which is denoted by $2. For example, if our custom git command is “git custom-branch test-branch parent-branch”, then $2 is parent-branch.

#21 Create the new branch from the user-provided parent branch.

#24 Create the new branch from the currently checked-out branch.

#27 Define the location of the file that will be used to store these parent-child relationships.

#29 Append the log of the newly created branch and its parent to the file defined in the previous step.

#30 Finally, check out the newly created branch.

Congratulations!!! You can now use this subcommand like below from any git repository on your local machine.

git custom-branch new_branch_name parent_branch_name

For practice, you can also try to create another subcommand to view the parent history, like this “git show-parent child_branch_name”.

Have fun! 🔥