Table of Contents
Overview
Do you love writing commit messages? If so, you can return to your development now 😛
For those of us who doesn’t enjoy writing commit messages very much, there is a solution.
Let me walk you through how to commit without you writing the commit message but let the AI do that.
I posted a video version of this post here, check it out if you are more of a visual type:
Step by step to configure auto commit message
Step 1: Create a Groq account and API key
First, head to https://console.groq.com/ and register an account
Next, go to https://console.groq.com/keys to generate your keys
Save your key some where safe, Groq doesn’t show it again to you.
Step 2: Configure your GROQ_API_KEY environment variable
On mac/linux, run
export GROQ_API_KEY=YOUR_KEY_HERE
To save the key permanently, edit your ~/.zshrc or ~/.bashrc and enter the above line
On windows, you can do this:
$env:GROQ_API_KEY="YOUR_KEY_HERE"
To store it permanently, you can set the environment variable in the windows (check this out https://docs.oracle.com/cd/E83411_01/OREAD/creating-and-modifying-environment-variables-on-windows.htm)
Step 3: Create the script for prepare-commit-msg hook
Create the following file .git/hooks/prepare-commit-msg and make it executable. On windows, you can open git bash to run the following commands
touch .git/hooks/prepare-commit-msg chmod +x .git/hooks/prepare-commit-msg
Now, here is the content of that file:
#!/bin/bash # File where the commit message will be written COMMIT_MSG_FILE=$1 # Log file for debugging purposes LOG_FILE=".git/groq_api_debug.log" # Check if the API key environment variable is set if [ -z "$GROQ_API_KEY" ]; then echo "Error: GROQ_API_KEY is not set. Please set it in your environment." exit 1 fi # Function to escape JSON safely across platforms using Python escape_json() { printf '%s' "$1" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))' } # Function to check if the commit message contains "skip llm" check_skip_llm() { # Read the user-provided commit message local user_commit_message=$(cat "$COMMIT_MSG_FILE") # Check if the commit message contains "skip llm" (case insensitive) if echo "$user_commit_message" | grep -qi "skip llm"; then # Remove the "skip llm" phrase (case insensitive) local cleaned_message=$(echo "$user_commit_message" | sed 's/skip llm//Ig') # Log that the user message is being used echo "User-provided commit message with 'skip llm' detected. Using user message." >> "$LOG_FILE" # Write the cleaned message to the commit message file echo "$cleaned_message" > "$COMMIT_MSG_FILE" # Exit the script, skipping the LLM generation exit 0 fi } # Function to generate a commit message from Groq API using Llama3 8b generate_commit_message() { # Capture the Git diff of staged changes local git_diff=$(git diff --cached) # If there's no diff, exit early if [ -z "$git_diff" ]; then echo "No changes detected. Using default commit message." >> "$LOG_FILE" exit 0 fi # Escape the git diff to make it JSON-safe (handling double quotes, newlines, etc.) local git_diff_escaped=$(echo "$git_diff" | sed 's/"/\\"/g') # Define the prompt with the Git changes local prompt="Generate a detailed commit message for the following changes without any extra explanations: $git_diff_escaped" # Escape the entire prompt to ensure it's JSON safe local prompt_escaped=$(escape_json "$prompt") # Log the prompt echo "==== INPUT to Groq API ====" >> "$LOG_FILE" echo "$prompt_escaped" >> "$LOG_FILE" # Example payload for the Groq API with the Git diff included local payload=$(cat <<EOF { "messages": [ { "role": "user", "content": $prompt_escaped } ], "model": "llama3-groq-70b-8192-tool-use-preview", "temperature": 1, "max_tokens": 1024, "top_p": 1, "stream": false, "stop": null } EOF ) # Log the payload being sent echo "==== Payload to Groq API ====" >> "$LOG_FILE" echo "$payload" >> "$LOG_FILE" # Make a POST request to the Groq API using the API key and store the response in a variable local response=$(curl -s -X POST "https://api.groq.com/openai/v1/chat/completions" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $GROQ_API_KEY" \ -d "$payload") # Log the full API response echo "==== API Response ====" >> "$LOG_FILE" echo "$response" >> "$LOG_FILE" # Use Python to parse the response and extract the commit message local commit_message=$(echo "$response" | python3 -c 'import json,sys; response = json.load(sys.stdin); print(response["choices"][0]["message"]["content"] if "choices" in response else "null")') # Log the extracted commit message echo "==== Extracted Commit Message ====" >> "$LOG_FILE" echo "$commit_message" >> "$LOG_FILE" # If the API returned null, log an error and exit if [ -z "$commit_message" ] || [ "$commit_message" == "null" ]; then echo "Error: No commit message generated by Groq API." >> "$LOG_FILE" exit 1 fi # Write the generated commit message to the commit message file echo "$commit_message" > "$COMMIT_MSG_FILE" } check_skip_llm # Call the function to generate the commit message generate_commit_message exit 0
The script basically calls GROQ to get the commit messages based on your changes.
Skipping LLM
There are times you want to skip calling the LLM for commit messages (you are commit package-lock.json for example), in such case, you can prepend the message with “skip llm” to use your literal message.
Of course, you can change the prefix to something else, just modify the script.
and that’s it!
Oh, by the way, you need to have python3 installed on your system
Conclusion
That’s how you free yourself from writing commit message. Have fun!
I build softwares that solve problems. I also love writing/documenting things I learn/want to learn.