Automate git commit messages with a simple bash script and openrouter

I like to automate as much work as possible. Here's a simple shell / bash script I'm using to save time by automatically creating git commit messages. 3 steps to get this to work: Sign up for Openrouter (A unified API for LLM models) Add your OPENROUTER_API_KEY to your environment variables (or paste it directly into the script below, replacing $OPENROUTER_API_KEY) Add the below script to your ~/.bash_aliases or ~/.bashrc or equivalent Refresh your terminal and you're good to go. You can now generate AI commit messages automatically by typing gca into your terminal. function gca() { local commit_message="$1" local push_remote="$2" # Check if Git is installed if ! command -v git &> /dev/null; then echo "Git is not installed. Please install Git and try again." return 1 fi # Check if jq is installed if ! command -v jq &> /dev/null; then echo "jq is not installed. Please install jq and try again." return 1 fi # Get the current Git repository local repo=$(git rev-parse --show-toplevel 2> /dev/null) if [ -z "$repo" ]; then echo "Not a Git repository. Please navigate to a Git repository and try again." return 1 fi # Check for manual commit message. If provided, use it and exit. if [ -n "$commit_message" ]; then echo "Using manual commit message: $commit_message" git add --all git commit -am "$commit_message" [ -n "$push_remote" ] && git push origin HEAD return 0 fi # Get the diff of the modified files (staged and unstaged) local diff=$(git diff HEAD) if [ -z "$diff" ]; then echo "No changes to commit." return 0 fi # Escape the diff for JSON local escaped_diff=$(echo "$diff" | jq -Rs .) if [ $? -ne 0 ]; then echo "Failed to escape diff content" return 1 fi local system_message="You are a master programmer who generates concise and informative Git commit messages. Explain why we have made the changes. If I remove a TODO, mention if the commit completed the task. Write a " local user_message=$(printf "Write a concise Git commit message for the following changes: Diff: %s. Only output the commit message, no other text. Use plain language to explain why the changes were made. You must exclude any formatting characters such as \`\`\` from your output. The first character of your output must be a capital letter. Write in highly succinct sentences. Never use the word 'Refactor'." "$escaped_diff") # Construct the JSON payload using jq local json_data=$(jq -n \ --arg sm "$system_message" \ --arg um "$user_message" \ '{ "model": "google/gemini-2.0-flash-lite-001", "messages": [ {"role": "system", "content": $sm}, {"role": "user", "content": $um} ] }') if [ $? -ne 0 ]; then echo "Failed to construct JSON payload" return 1 fi # Make the API call local api_response=$(curl --silent --show-error "https://openrouter.ai/api/v1/chat/completions" \ -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -d "$json_data") # Check if the API call was successful if [ $? -ne 0 ]; then echo "Error calling the API. Please check your internet connection and try again." return 1 fi echo "API Response: $api_response" echo "\n\n" # Extract the commit message using jq local commit_message=$(jq -r ".choices[0].message.content"

May 13, 2025 - 23:44
 0
Automate git commit messages with a simple bash script and openrouter

I like to automate as much work as possible. Here's a simple shell / bash script I'm using to save time by automatically creating git commit messages.

3 steps to get this to work:

  1. Sign up for Openrouter (A unified API for LLM models)
  2. Add your OPENROUTER_API_KEY to your environment variables (or paste it directly into the script below, replacing $OPENROUTER_API_KEY)
  3. Add the below script to your ~/.bash_aliases or ~/.bashrc or equivalent

Refresh your terminal and you're good to go.
You can now generate AI commit messages automatically by typing gca into your terminal.

function gca() {
    local commit_message="$1"
    local push_remote="$2"

    # Check if Git is installed
    if ! command -v git &> /dev/null; then
        echo "Git is not installed. Please install Git and try again."
        return 1
    fi

    # Check if jq is installed
    if ! command -v jq &> /dev/null; then
        echo "jq is not installed. Please install jq and try again."
        return 1
    fi

    # Get the current Git repository
    local repo=$(git rev-parse --show-toplevel 2> /dev/null)
    if [ -z "$repo" ]; then
        echo "Not a Git repository. Please navigate to a Git repository and try again."
        return 1
    fi

    # Check for manual commit message. If provided, use it and exit.
    if [ -n "$commit_message" ]; then
        echo "Using manual commit message: $commit_message"
        git add --all
        git commit -am "$commit_message"
        [ -n "$push_remote" ] && git push origin HEAD
        return 0
    fi

    # Get the diff of the modified files (staged and unstaged)
    local diff=$(git diff HEAD)
    if [ -z "$diff" ]; then
        echo "No changes to commit."
        return 0
    fi

    # Escape the diff for JSON
    local escaped_diff=$(echo "$diff" | jq -Rs .)
    if [ $? -ne 0 ]; then
        echo "Failed to escape diff content"
        return 1
    fi

    local system_message="You are a master programmer who generates concise and informative Git commit messages. Explain why we have made the changes. If I remove a TODO, mention if the commit completed the task. Write a "

    local user_message=$(printf "Write a concise Git commit message for the following changes: Diff: %s. Only output the commit message, no other text. Use plain language to explain why the changes were made. You must exclude any formatting characters such as \`\`\` from your output. The first character of your output must be a capital letter. Write in highly succinct sentences. Never use the word 'Refactor'." "$escaped_diff")

    # Construct the JSON payload using jq
    local json_data=$(jq -n \
      --arg sm "$system_message" \
      --arg um "$user_message" \
      '{
        "model": "google/gemini-2.0-flash-lite-001",
        "messages": [
          {"role": "system", "content": $sm},
          {"role": "user", "content": $um}
        ]
      }')

    if [ $? -ne 0 ]; then
        echo "Failed to construct JSON payload"
        return 1
    fi

    # Make the API call
    local api_response=$(curl --silent --show-error "https://openrouter.ai/api/v1/chat/completions" \
      -X POST \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer $OPENROUTER_API_KEY" \
      -d "$json_data")

    # Check if the API call was successful
    if [ $? -ne 0 ]; then
        echo "Error calling the API. Please check your internet connection and try again."
        return 1
    fi

    echo "API Response: $api_response"
    echo "\n\n"


    # Extract the commit message using jq
    local commit_message=$(jq -r ".choices[0].message.content" <<< "$api_response")

    # Check if the commit message is empty or null
    if [ -z "$commit_message" ]; then
        echo "Failed to generate a commit message."
        echo "API response: $api_response"
        return 1
    fi

    # Stage and commit all files (staged and unstaged)
    echo "Message: $commit_message"
    git add --all
    git commit -am "$commit_message"

    # Push to remote if specified
    [ -n "$push_remote" ] && git push origin HEAD

    return 0
}

alias gca=gca

The model is set to Gemini 2 Flash Lite. This is a model that's smart enough for creating commit messages, and which is cheap and fast enough not to interrupt your git flow.