Writing a Conventional Commits Helper
Oct 23, 2025 (3 days ago)Contents
- Why write another one?
- Few utilities
- Conventional Commits
- Accessing user input and building the message
- Confirmation
- Demo
- References
Why write another one?
I am aware that there are existing tools that help you author your commit messages in the style of conventional commits. I have myself been using cz-git for a long while when I was first getting into formatting my commit messages better and using conventional commit style. It is a perfectly fine tool and honestly I have looked into how it's working to take inputs in my own shell script which implements the same.
I myself think that while it is good that the CLI I mentioned above has a plugin system that enables different cases to be handled on a per use-case basis, I am using the same thing over and over and can use something more better than JavaScript.
I remember I tried searching for some Go packages to help with this, (and maybe Rust?) but I didn't find anything useful. Hence I set forth to write my own small helper script.
Few utilities
It is nice to have some utilities and functions to make the repetitive code structure easier to reuse or to just use good tools for input from user.
Some of them are:
gum- A tool from Charm which provides highly configurable, ready-to-use utilities for writing shell scripts. They have their own little example for writing a conventional commit helper (meta!)- A little function
check_existsthat checks whether a command is installed and exits otherwise
Code for check_exists
- A function
check_added_filesto check whether we have added any files to Git at all before going to commit the changes.
Code for check_added_files
Conventional Commits
You can find the full specification at conventionalcommits.org. However for a quick refresher at the different parts is below.
A typical commit structured with conventional commit looks as follows:
Let us look at the implementation that takes in all the different parts from the user.
Accessing user input and building the message
Type
The type can be one of some predefined ones. There can be more depending on the project and other adapters. We store them in an array to access them later.
If you are familiar with fzf, you can use gum choose or gum filter to get a picker for the different types above.
Scope
The scope of the commit is optional and must be in brackets after the type. We handle the optional case by looking at the return value from the gum input command and add it to the commit if provided.
Breaking change?
A breaking change MUST have either a note in the footer or a ! after the type and scope. We ask whether it is one or not using gum choose and looking at the return value from the command which reflects the user's choice.
A breaking change should have a note in the footer to be appended in the description. I do not do that here, but it is just one more input before the final confirmation.
Commit message
Next, we ask the user for the actual commit message. We have a comfortable character limit for easy viewing capped at 50 characters using --char-limit flag. This is one of the last time we get to abort the commit by supplying an empty commit message.
Description
There might be an extended description of the commit which can then be accessed via other git commands. We include them in an input box from the user.
Confirmation
We confirm the user for the final commit and depending on whether we have a description or not, we add a newline in between for the final commit message.
Demo
Here's a gif for the demo:
Demo of my script for conventional commits making an initial git commit
Details of the commit message for the initial commit which is now formatted as per conventional commit.