Created
March 17, 2025 19:58
-
-
Save mgaitan/231efe9155e4d000ec0282f14c1d2fba to your computer and use it in GitHub Desktop.
llm powered git commit message
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
#!~/.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