Last active
December 15, 2023 09:53
-
-
Save antoinejeannot/efaa44a9de5b10024eac993034ce3a62 to your computer and use it in GitHub Desktop.
Minimalist & Easy-to-hack LLM-powered git message
This file contains 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 | |
########################################################################### | |
# Automatically generates a git commit message based on `git diff` and a LLM | |
# Minimalist & Easy-to-hack implementation: | |
# . It relies on git hooks | |
# . it requires `jq` (brew install jq) for json management | |
# | |
# . Usage: prefix your git commit message by "auto" | |
# .. git commit -m "auto" | |
# .. [refact-cleaner 920c1da8]: refactor: remove import of "collections" and "itertools" from cleaner.py | |
# | |
# . Setup: replace / adapt your [PROJECT]/.git/hooks/prepare-commit-msg with this file | |
# .. By default, it targets OpenAI's API and uses the gpt-3.5-turbo model | |
# .. You need to install `jq` if not already installed: `brew install jq` | |
# | |
# . PARAMETERS: | |
# .. GIT_LLM_API env variable: API following the standard /chat/generations API interface, defaults to OpenAI | |
# .. GIT_LLM_MODEL env variable: Model name to leverage, defaults to gpt-3.5-turbo | |
# | |
# Feel free to hack it ! There is certainly a ton of improvements to be made :) | |
# | |
# Author: Antoine Jeannot | |
# GitHub: https://github.com/antoinejeannot | |
# License: MIT License | |
########################################################################### | |
# Get the current commit message | |
if [ "$2" = "merge" ] || [ "$2" = "commit" ]; then | |
exit | |
fi | |
commit_msg_file="$1" | |
commit_msg=$(cat "$commit_msg_file") | |
if [[ $commit_msg == "auto"* ]]; then | |
llm_api="${GIT_LLM_API:-https://api.openai.com/v1/chat/completions}" | |
llm_model="${GIT_LLM_MODEL:-gpt-3.5-turbo}" | |
# Prepend the prefix to the commit message | |
# Replace the system and user messages as needed | |
system_message='You are the best git assistant whose aim is to generate a git commit message. | |
IT MUST BE written in English, be concise, be lowercase, relevant and straight to the point. | |
IT MUST FOLLOW conventional commits specifications and the following template: | |
<type>[optional scope]: <short description> | |
[optional body] | |
Where <type> MUST BE ONE OF: fix, feat, build, chore, ci, docs, style, refactor, perf, test | |
Where <type> MUST NOT BE: add, update, delete etc. | |
A commit that has a footer BREAKING CHANGE:, or appends a ! after the type, introduces a breaking API change. | |
DO NOT ADD UNDER ANY CIRCUMSTANCES: explanation about the commit, details such as file, changes, hash or the conventional commits specs. | |
Here is the git diff: | |
' | |
# Correctly capture system message in JSON format | |
system_message=$(jq -sR . <<< "$system_message") | |
# Capture git diff output | |
git_diff=$(git diff --cached $file --unified=0 --minimal) | |
# Convert git_diff to JSON format | |
git_diff=$(jq -sR . <<< "$git_diff") | |
# Create JSON payload | |
json_data=$(jq -n \ | |
--arg system_message "$system_message" \ | |
--arg git_diff "$git_diff" \ | |
--arg llm_model "$llm_model" \ | |
'{ | |
"model": $llm_model, | |
"messages": [ | |
{ | |
"role": "system", | |
"content": $system_message | |
}, | |
{ | |
"role": "user", | |
"content": $git_diff | |
} | |
] | |
}' | |
) | |
# Make the API call and store the result in $commit_msg | |
result=$(curl -s "$llm_api" -H "Content-Type: application/json" -H "Authorization: Bearer ${OPENAI_API_KEY}" -d "$json_data") | |
commit_msg=$(echo "$result" | jq -r '.choices[0].message.content') | |
total_tokens=$(echo "$result" | jq '.usage.total_tokens') | |
echo "LLM API - Total tokens used: $total_tokens" | |
fi | |
echo -e "$commit_msg" > "$commit_msg_file" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment