Skip to content

Instantly share code, notes, and snippets.

@mgaitan
Created March 17, 2025 19:58
Show Gist options
  • Save mgaitan/231efe9155e4d000ec0282f14c1d2fba to your computer and use it in GitHub Desktop.
Save mgaitan/231efe9155e4d000ec0282f14c1d2fba to your computer and use it in GitHub Desktop.
llm powered git commit message
#!~/.local/share/uv/tools/llm/bin/python
"""
Git hook script for automatically generating commit messages using llm.
Installation:
1. Install `llm` if not already installed:
uv tool install llm
2. Install and configure a model (e.g., gemini):
llm install llm-gemini
llm keys set gemini
<paste>
llm models default gemini-2.0-flash
3. Save this script as `.git/hooks/prepare-commit-msg` inside your repository.
4. Make it executable:
chmod +x .git/hooks/prepare-commit-msg
Now, whenever you commit, the hook will automatically generate a commit message based on staged changes.
"""
import subprocess
import sys
from pathlib import Path
import llm
def get_staged_diff():
"""Obtain the staged diff."""
result = subprocess.run(["git", "diff", "--staged"], capture_output=True, text=True)
return result.stdout
def generate_commit_message(diff):
"""Use llm to generate a commit message based on the diff."""
model_name = llm.get_default_model() # Get the configured model name
model = llm.get_model(model_name) # Retrieve the actual model instance
prompt = f"Generate a concise commit message for the following diff:\n{diff}"
response = model.prompt(prompt) # Get the response directly
return response.text().strip() # Use .text() to extract the generated message
def main():
if len(sys.argv) < 2:
print("Usage: prepare-commit-msg <commit-msg-file> [commit-source] [SHA1]")
sys.exit(1)
commit_msg_path = Path(sys.argv[1])
diff = get_staged_diff()
if not diff.strip():
print("No staged changes detected.")
sys.exit(1)
commit_message = generate_commit_message(diff)
print("\nSuggested commit message:\n")
print(commit_message)
# Overwrite the commit message file only if it's a new commit (not amend, merge, or rebase)
if len(sys.argv) == 2: # Only modify if it's an interactive commit
commit_msg_path.write_text(commit_message, encoding="utf-8")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment