Goodbye, manual commits: I created a script with Gemini to generate commit messages (and you can too)
A practical experiment in commit automation: I used the Gemini CLI to generate consistent, clear commit messages aligned with Conventional Commits. The idea was to reduce the friction of writing commits without sacrificing quality and standardization.
Writing commit messages, besides being a somewhat tedious task, requires technique regarding semantics, patterns, and structure. Often, we spend valuable minutes just to draft a message that adequately describes the change. The situation becomes even more complicated when we need to write them in English: in this case, it's necessary to master not only the art of creating good messages but also the nuances of the language.
A light at the end of the tunnel
Recently, I decided to test JetBrains' AI tool to generate commit messages, and the experience was incredible. With just one click, the AI created messages following a pattern very close to Conventional Commits. However, at the end of the 30-day trial, I was not willing to pay for the subscription, mainly because nowadays it's very simple to integrate artificial intelligence solutions into the workflow.
What are Conventional Commits?
The Angular development team was, without a doubt, a precursor to a commit convention that inspired the pattern currently used. I won't go into detail about this pattern, as this article already offers an excellent explanation.
The only adaptation I usually make is to rarely use the scope of the change.
Customizing the message pattern
A good commit message usually starts with a verb in the imperative mood. A trick is to mentally complete the phrase: "If applied, this commit will...". Examples:
- If applied, this commit will... Add icon to login button
- If applied, this commit will... Fix typing error in form
- If applied, this commit will... Optimize memory usage in the service
Standardizing messages - GEMINI.md
Based on these two principles (imperative mood and Angular convention), I decided to create a file called GEMINI.md at the root of each project where I use AI.
When we create this file at the root of the project, the Gemini CLI automatically reads it and inserts its content into the request context. This allows defining specific rules and patterns for each project, making the process more standardized and reliable, in addition to ensuring consistency.
The solution
About two weeks ago, I installed the Gemini CLI and performed some tests to better understand the tool. The conclusion was clear: use the Gemini CLI to generate my commit messages.
Evidently, AI does not replace us. However, when well used as a tool, it helps us produce more, in less time, and with higher quality. It is, therefore, an excellent Pair Programming partner.
The first problems
When asking the CLI to generate commit messages, I encountered two immediate obstacles:
- Incorrect file reading: Gemini processed all modified files, even those not in stage. I tried varying the prompts, but without success.
- Slowness of the default model: The CLI used
gemini-2.5-pro, which took almost a minute to generate the message. I was already satisfied with the result ofgemini-2.5-flashand didn't want to wait four or five times longer. Of course, you can change the model via the CLI, but I didn't want to have to take that extra step with each commit.
Solution - Shell Script
To overcome the problems, I decided to create a Shell Script that centralized the instructions: use the gemini-2.5-flash model and capture only the files in stage.
Since it had been years since I wrote Shell Scripts, I didn't waste time trying to remember the syntax. I wrote a good prompt and asked the AI to generate it for me.
The AI made a mistake
The initial script validated some conditions and only then sent the information to the AI. However, the main command was this:
COMMIT_MSG=$(git diff --staged | gemini -m gemini-2.5-flash -p “Generate a concise commit message following the ‘Conventional Commits’ pattern for the following changes:”)
The problem was that the AI always returned that there were no files in stage. After debugging the code, I realized that the output of git diff --staged was not being correctly sent through the pipe. The solution was to store the output in a variable and concatenate it directly into the prompt:
STAGED_DIFF=$(git diff --staged) COMMIT_MSG=$(gemini -m gemini-2.5-flash -p “Generate a concise commit message following the ‘Conventional Commits’ pattern for the following changes: <changes>$STAGED_DIFF</changes>”)
In addition, I encapsulated the changes in XML-style tags (<changes>...</changes>), which helps the AI better contextualize the input.
Do not commit directly
I considered it essential to review the message before using it, both to avoid AI hallucinations and to take advantage of WebStorm's features, which suggest improvements and point out typing errors.
The initial solution was to display the output in the terminal. Later, I evolved the script to copy the message directly to the clipboard.
An evolution of the script
I also realized that, in certain cases, it would be useful to give additional context to the AI, such as informing that the change applied a specific design pattern or met a new platform requirement.
I adapted the script to accept an extra argument at execution time:
# Get user prompt if provided FOCUS="$1" if [ -n “$FOCUS” ]; then PROMPT="Generate a concise commit message following the ‘Conventional Commits’ pattern. Focus: \"$FOCUS\“. Here are the changes: <changes>$STAGED_DIFF</changes>” else PROMPT=“Generate a concise commit message following the ‘Conventional Commits’ pattern for the following changes: <changes>$STAGED_DIFF</changes>” fi # Generates the commit message with Gemini COMMIT_MSG=$(gemini -m gemini-2.5-flash -p “$PROMPT”)
Now it's possible to execute both $ commit and $ commit "refactoring to apply the strategy pattern".
The trick
After various tests and refinements, one question remained: how to make the execution as practical as JetBrains' button?
The answer was to save the script in the ~/bin/ directory with the name commit. Thus, in any terminal folder, just type $ commit and everything happens automatically.
Lessons learned
Although ready-made tools exist, the goal of this project was to build a solution from scratch to understand each step of the process. I believe that mastering the fundamentals makes us more complete developers.
An important warning about AI and privacy
It is crucial to remember data privacy. When using the Gemini CLI for free, you need to be aware that your prompts and code may be used to train future models.
In professional environments or with sensitive code, the correct approach is to use the API on platforms that guarantee privacy.
The appropriate alternatives are to migrate to Google AI Studio or, in corporate contexts, integrate the model via Vertex AI on the Google Cloud Platform. In these options, it is possible to disable data sharing, ensuring confidentiality. Furthermore, the cost per API usage tends to be significantly lower than subscribing to tools like those from JetBrains.
Conclusion
And you, how do you optimize your commit messages?
If you liked the solution, check out the complete repository on my GitHub and connect with me on LinkedIn to exchange more ideas.