Skip to content

Instantly share code, notes, and snippets.

@sergebulaev
Forked from karpathy/add_to_zshrc.sh
Last active October 1, 2024 11:25
Show Gist options
  • Select an option

  • Save sergebulaev/26934a593cce677001a47621319bbb9f to your computer and use it in GitHub Desktop.

Select an option

Save sergebulaev/26934a593cce677001a47621319bbb9f to your computer and use it in GitHub Desktop.
Git Commit Message AI
# -----------------------------------------------------------------------------
# AI-powered Git Commit Function
# Copy paste this function into your ~/.bashrc or ~/.zshrc to gain the `gcm` command. It:
# 1) Checks if there are any staged changes
# 2) Gets the current staged changes diff
# 3) Sends the diff to an LLM to generate a structured summary of changes
# 4) Sends the diff to an LLM to write a git commit message
# 5) Allows you to easily accept, edit, regenerate, or cancel the commit
# 6) Provides timestamp for successful commits or cancellations
#
# Requirements:
# - Git
# - LLM CLI utility (https://llm.datasette.io/en/stable/)
# - GPT-4-mini model available for LLM
# Extended lazy option to use:
# alias save="git add . && gcm && git push"
#
# Installation Instructions for LLM on Mac:
# 1. Install Homebrew if not already installed:
# /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# 2. Install LLM using Homebrew:
# brew install llm
# 3. Verify installation:
# llm --version
# 4. (Optional) Set up OpenAI API key:
# llm keys set openai
gcm() {
# Check if there are any staged changes
if [ -z "$(git diff --cached)" ]; then
echo "No staged changes. Nothing to commit."
return 1
fi
# Function to get structured summary of changes
get_change_summary() {
git diff --cached | llm -m 4o-mini "
Below is a diff of all staged changes. Provide an extremely brief, very short, structured summary of what was removed and added. If there are no removals or additions in a category, omit it entirely. Format:
Removed:
- Key point 1
- Key point 2
Added:
- Key point 1
- Key point 2
Be as concise as possible, focusing only on the most significant changes. Text only, no markdown."
}
# Function to generate commit message
generate_commit_message() {
git diff --cached | llm -m 4o-mini "
Below is a diff of all staged changes, coming from the command:
\`\`\`
git diff --cached
\`\`\`
Please generate a concise, one-line commit message for these changes."
}
# Function to read user input compatibly with both Bash and Zsh
read_input() {
if [ -n "$ZSH_VERSION" ]; then
echo -n "$1"
read -r REPLY
else
read -p "$1" -r REPLY
fi
}
# Main script
echo "Generating AI-powered change summary..."
change_summary=$(get_change_summary)
echo -e "\nChange Summary:"
echo "$change_summary"
echo -e "\nGenerating AI-powered commit message..."
commit_message=$(generate_commit_message)
while true; do
echo -e "\nProposed commit message:"
echo "$commit_message"
read_input "Do you want to (a)ccept, (e)dit, (r)egenerate, or (c)ancel? [a] "
choice=$REPLY
case "$choice" in
""|a|A )
if git commit -m "$commit_message"; then
echo "Changes committed successfully!"
echo "Commit time: $(date)"
return 0
else
echo "Commit failed. Please check your changes and try again."
return 1
fi
;;
e|E )
read_input "Enter your commit message: "
new_message=$REPLY
if [ -n "$new_message" ]; then
commit_message=$new_message
fi
if git commit -m "$commit_message"; then
echo "Changes committed successfully with your message!"
echo "Commit time: $(date)"
return 0
else
echo "Commit failed. Please check your message and try again."
return 1
fi
;;
r|R )
echo "Regenerating commit message..."
commit_message=$(generate_commit_message)
;;
c|C )
echo "Commit cancelled."
echo "Cancellation time: $(date)"
return 1
;;
* )
echo "Invalid choice. Please try again."
;;
esac
done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment