Last active
June 16, 2025 21:12
-
-
Save kenchopa/d46c940f2bc28ef5959b381f2d02dd0b to your computer and use it in GitHub Desktop.
openai generated auto commit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -euo pipefail | |
| exec > /tmp/prepare-commit-msg.log 2>&1 | |
| echo "βοΈ prepare-commit-msg hook starting..." | |
| COMMIT_MSG_FILE="${1:-}" | |
| COMMIT_SOURCE="${2:-}" | |
| COMMIT_SHA="${3:-}" | |
| echo "π COMMIT_MSG_FILE: $COMMIT_MSG_FILE" | |
| echo "π COMMIT_SOURCE: $COMMIT_SOURCE" | |
| echo "π’ COMMIT_SHA: $COMMIT_SHA" | |
| # Skip for merge, squash, rebase, etc. | |
| if [[ -n "$COMMIT_SOURCE" ]]; then | |
| echo "βΉοΈ Commit source provided ($COMMIT_SOURCE). Skipping hook." | |
| exit 0 | |
| fi | |
| # Check if jq is installed | |
| if ! command -v jq > /dev/null; then | |
| echo "β jq is not installed. Please install jq to continue." | |
| exit 1 | |
| fi | |
| # Check for OpenAI key | |
| if [[ -z "${OPENAI_API_KEY:-}" ]]; then | |
| echo "β OPENAI_API_KEY is not set. Skipping AI commit message." | |
| exit 0 | |
| fi | |
| echo "π OPENAI_API_KEY detected" | |
| # Get staged changes | |
| echo "π Checking for staged diff..." | |
| GIT_DIFF=$(git diff --cached) | |
| if [[ -z "$GIT_DIFF" ]]; then | |
| echo "β No staged changes to describe." | |
| exit 0 | |
| fi | |
| echo "β Staged diff found" | |
| # Build OpenAI prompt | |
| echo "π Preparing OpenAI prompt..." | |
| PROMPT=$(cat <<EOF | |
| Generate a concise, conventional commit message based on the following git diff. | |
| Use the Conventional Commits format (e.g., feat:, fix:, chore:, docs:, refactor:, test:). | |
| Summarize the intent clearly. Do not include file paths or code snippets. | |
| Git diff: | |
| $GIT_DIFF | |
| EOF | |
| ) | |
| # Escape prompt using jq to ensure valid JSON | |
| ESCAPED_PROMPT=$(jq -Rs . <<< "$PROMPT") | |
| # Send to OpenAI | |
| echo "π‘ Sending request to OpenAI..." | |
| RAW_RESPONSE=$(curl -sS -w "\n%{http_code}" https://api.openai.com/v1/chat/completions \ | |
| -H "Authorization: Bearer $OPENAI_API_KEY" \ | |
| -H "Content-Type: application/json" \ | |
| -d @- <<EOF | |
| { | |
| "model": "gpt-4", | |
| "messages": [ | |
| { | |
| "role": "user", | |
| "content": $ESCAPED_PROMPT | |
| } | |
| ], | |
| "temperature": 0.3 | |
| } | |
| EOF | |
| ) | |
| # Split response and status | |
| HTTP_BODY=$(echo "$RAW_RESPONSE" | sed '$d') | |
| HTTP_STATUS=$(echo "$RAW_RESPONSE" | tail -n1) | |
| echo "π¨ Raw response (HTTP $HTTP_STATUS):" | |
| echo "$HTTP_BODY" | |
| # Check status code | |
| if [[ "$HTTP_STATUS" != "200" ]]; then | |
| echo "β OpenAI API returned HTTP $HTTP_STATUS" | |
| echo "β οΈ Commit aborted." | |
| exit 1 | |
| fi | |
| # Check for OpenAI error message | |
| OPENAI_ERROR=$(echo "$HTTP_BODY" | jq -r '.error.message // empty') | |
| if [[ -n "$OPENAI_ERROR" ]]; then | |
| echo "β OpenAI error: $OPENAI_ERROR" | |
| exit 1 | |
| fi | |
| # Parse message content | |
| COMMIT_MESSAGE=$(echo "$HTTP_BODY" | jq -r '.choices[0].message.content // empty') | |
| if [[ -z "$COMMIT_MESSAGE" ]]; then | |
| echo "β Failed to parse commit message from response." | |
| exit 1 | |
| fi | |
| echo "β Commit message received" | |
| # Prompt user (supports non-interactive fallback) | |
| echo "" | |
| echo "π€ Suggested commit message:" | |
| echo "----------------------------------" | |
| echo "$COMMIT_MESSAGE" | |
| echo "----------------------------------" | |
| echo "" | |
| if [[ -t 0 ]]; then | |
| echo "Options:" | |
| echo "[a] Accept" | |
| echo "[e] Edit" | |
| echo "[c] Cancel commit" | |
| read -p "Your choice [a/e/c]: " choice | |
| else | |
| echo "β οΈ Non-interactive shell detected. Auto-accepting commit message." | |
| choice="a" | |
| fi | |
| case "$choice" in | |
| a|A) | |
| echo "$COMMIT_MESSAGE" > "$COMMIT_MSG_FILE" | |
| echo "πΎ Message accepted and written" | |
| ;; | |
| e|E) | |
| TMPFILE=$(mktemp) | |
| echo "$COMMIT_MESSAGE" > "$TMPFILE" | |
| echo "π Opening editor: ${EDITOR:-vim}" | |
| ${EDITOR:-vim} "$TMPFILE" | |
| cat "$TMPFILE" > "$COMMIT_MSG_FILE" | |
| rm "$TMPFILE" | |
| echo "βοΈ Message edited and written" | |
| ;; | |
| c|C) | |
| echo "β Commit cancelled by user." | |
| exit 1 | |
| ;; | |
| *) | |
| echo "β οΈ Invalid option. Commit cancelled." | |
| exit 1 | |
| ;; | |
| esac |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
π€ prepare-commit-msg: AI-Powered Git Commit Messages
This Git hook automatically generates commit messages using the OpenAI GPT-4 API, based on your staged changes. It follows the Conventional Commits specification to keep your commit history consistent and meaningful.
β¨ Features
feat:,fix:,chore:, etc.)/tmp/prepare-commit-msg.logπ οΈ Installation
1. Save the script as a Git hook
2. Install dependencies
Make sure both
jqandcurlare installed on your system:macOS (Homebrew):
Ubuntu/Debian:
Arch Linux:
Windows (via Chocolatey):
3. Set your OpenAI API key
You must provide your OpenAI API key to allow the hook to send requests to the GPT-4 API.
π Option 1: Export manually (for current session)
π Option 2: Persist the key in your shell configuration
To automatically load your
OPENAI_API_KEYevery time you open a terminal, add it to your shell config file.For Bash (
~/.bashrcor~/.bash_profile):For Zsh (
~/.zshrc):For Fish shell:
π Usage
Stage your changes:
git add .Commit as usual:
The hook will:
[a]Accept[e]Edit[c]CancelIf you're in a non-interactive shell (like CI), the message will be auto-accepted.
π Environment Requirements
OPENAI_API_KEYmust be setjqmust be installedβ Skipping the Hook
To skip the hook (e.g., for merge commits or CI):
π License
MIT β free to use and modify. Credit is appreciated but not required.