Tutorials & Guides
How to Build an Automated Git Commit Message Generator with Gemini 1.5 Flash and Git Hooks
Tired of writing lazy commit messages? Learn how to automate descriptive, Conventional Commits format messages using Gemini 1.5 Flash and a local pre-commit Git hook.
Updated 10/7/2026
Automated Diffs, Cleaner Repositories
Let’s be honest: writing good commit messages is a chore. Despite your team's best efforts to enforce tidy repositories, most git histories end up looking like a depressing string of "fixed stuff", "temp commit", and "please work".
Writing clean, structured commit messages is vital for semantic versioning, readable changelogs, and sanity-saving rollbacks. But we shouldn’t be spending mental energy formatting them manually. Instead, we can build a local automation script that intercepts your staged changes, passes the code diffs to Gemini 1.5 Flash, and drafts a highly descriptive commit message matching the Conventional Commits specification.
In this step-by-step guide, we will write a local Python automation script and bind it to a native git hook.
Why Gemini 1.5 Flash?
For local developer experience automations, speed and API cost are the only metrics that matter. Gemini 1.5 Flash has near-instant generation times, zero startup cold-starts, and a massive context window that can handle massive code diffs if you happen to stage an unusually large change. Crucially, its price makes running local dev automations practically free.
If you run into issues configuring your integration with the Google AI SDK, head over to our dedicated Gemini troubleshooting workspace.
Step 1: Install the Requirements
First, make sure you have Python 3 installed. Navigate to your target Git repository where you want to apply the hook, and install the official Google GenAI library:
`bash
pip install google-genai dotenv
`
Set up your Gemini API key in your system environment variables. In Linux or macOS, add this to your shell profile (.bashrc or .zshrc):
`bash
export GEMINI_API_KEY="your-gemini-api-key-here"
`
Step 2: Build the Commit Message Generator Script
We need a script that extracts current staged code changes using git diff, sends them to Gemini with explicit system instructions, and returns a formatted message.
Create a python file inside your repository named .githooks/generate_commit.py:
`python
#!/usr/bin/env python3
import subprocess
import sys
import os
from google import genai
def get_git_diff(): # Get staged changes only try: diff = subprocess.check_output(["git", "diff", "--cached"]).decode("utf-8") return diff except subprocess.CalledProcessError as e: print(f"Error getting git diff: {e}") sys.exit(1)
def generate_commit_message(diff_text): if not diff_text.strip(): return ""
Initialize the Gemini Client client = genai.Client() prompt = f""" Analyze the following Git diff of staged files and write an informative, clear, and concise commit message following the Conventional Commits format. Format: <type>(<scope>): <short description> [optional body] Allowed Types: - feat: A new feature - fix: A bug fix - docs: Documentation changes - style: Formatting, missing semi-colons, no production code change - refactor: Refactoring code without behavior changes - test: Adding missing tests or correcting existing tests - chore: Build process or auxiliary tool changes Rules: - Use the imperative present tense ("add", not "added") - Keep the first line under 72 characters - Provide a short bulleted list in the body explaining the 'why' if the changes are complex - Output ONLY the raw commit message. Do not include markdown code block backticks. Staged Changes Diff: {diff_text} """ try: response = client.models.generate_content( model='gemini-1.5-flash', contents=prompt, ) return response.text.strip() except Exception as e: print(f"Failed to generate message from Gemini API: {e}") sys.exit(1)
def main(): # Ensure we are inside a Git repository if not os.path.exists(".git"): print("Not a Git repository.") sys.exit(1)
diff_text = get_git_diff()
if not diff_text:
print("No staged files found. Please stage changes using git add first.")
sys.exit(0)
print("Analyzing staged code changes and querying Gemini 1.5 Flash...") commit_msg = generate_commit_message(diff_text) if commit_msg: # Write to a temporary file for git to read with open(".git/COMMIT_EDITMSG", "w") as f: f.write(commit_msg) print("\n--- Draft Commit Message Generated ---") print(commit_msg) print("--------------------------------------") else: print("No changes detected.")
if __name__ == "__main__":
main()
`
Step 3: Wire Up the Git Hook
Git hooks are native scripts stored in .git/hooks/ that run automatically when Git events trigger. We want to run our Python script right before the user commits, giving them the chance to preview and edit the AI-generated message.
We will use the prepare-commit-msg hook. Create or open the file .git/hooks/prepare-commit-msg:
`bash
touch .git/hooks/prepare-commit-msg
chmod +x .git/hooks/prepare-commit-msg
`
Open .git/hooks/prepare-commit-msg in your favorite text editor and paste the following bash instructions:
`bash
#!/bin/sh
# Prepare commit message hook to run our Gemini script
Skip execution if committing during a merge or rebase if [ "$2" = "merge" ] || [ "$2" = "squash" ]; then exit 0 fi
Run our Python commit generator python3 .githooks/generate_commit.py ```
Testing Your Automated Commit Generation
Let's tick this workflow off and see it in action. Make a minor modification to a script file in your repository, stage it with git add, and trigger the commit process:
`bash
git add src/main.py
git commit
`
Your terminal will run the Python pipeline, fetch the diff, send it off to Gemini, write the draft message directly into Git’s commit edit buffer, and immediately open your default command line text editor (Nano, Vim, or VS Code) with a beautifully pre-formatted Conventional Commit message waiting for you to save or tweak.
No more lazy logs, no more spent brain cycles. If you are curious about the mechanical terms behind modern LLM capabilities like temperature, chunking, and system variables used in this automation, check out our comprehensive glossary.
Keep going
Build something with the prompt generator, decode the jargon in the glossary, or compare the tools on our platform deep-dives.