Skip to content

Instantly share code, notes, and snippets.

@dmzoneill
Created April 11, 2025 14:13
Show Gist options
  • Save dmzoneill/80bfef9603448c33df02ce0aa98fcd59 to your computer and use it in GitHub Desktop.
Save dmzoneill/80bfef9603448c33df02ce0aa98fcd59 to your computer and use it in GitHub Desktop.
AI git Commit
#!/usr/bin/python3
import os
import sys
import requests
import subprocess
import argparse
class OpenAIProvider:
def __init__(self):
self.api_key = os.getenv("AI_API_KEY")
if not self.api_key:
raise EnvironmentError("AI_API_KEY not set in environment.")
self.endpoint = "https://api.openai.com/v1/chat/completions"
self.model = os.getenv("OPENAI_MODEL", "gpt-4o-mini")
def improve_text(self, prompt: str, text: str) -> str:
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
}
body = {
"model": self.model,
"messages": [
{"role": "system", "content": prompt},
{"role": "user", "content": text},
],
"temperature": 0.3,
}
response = requests.post(self.endpoint, json=body, headers=headers, timeout=30)
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"].strip()
raise Exception(
f"OpenAI API call failed: {response.status_code} - {response.text}"
)
def get_diff_from_stdin():
"""Reads the diff from stdin (useful for piped input)."""
return sys.stdin.read()
def get_diff_from_git():
"""Runs 'git diff HEAD~1' and captures the output."""
return subprocess.check_output(
"GIT_PAGER=cat git diff HEAD~1", shell=True, text=True
)
def main():
# Step 1: Parse command-line arguments
parser = argparse.ArgumentParser(description="Generate and commit a git commit message.")
parser.add_argument(
"--print", action="store_true", help="Print the commit message without creating the commit"
)
args = parser.parse_args()
# Step 2: Get the current working directory
cwd = os.getcwd()
# Step 3: Get the diff
diff = None
if not sys.stdin.isatty():
print("Reading git diff from stdin...")
diff = get_diff_from_stdin()
else:
print("Getting git diff from HEAD~1...")
diff = get_diff_from_git()
if not diff:
print("No diff found, nothing to commit.")
return
# Step 4: Prepare the prompt for OpenAI
prompt = "Take the diff and give me a good commit message, give me the commit message and nothing else"
# Create an instance of OpenAIProvider
openai_provider = OpenAIProvider()
# Step 5: Get the commit message from OpenAI
print("Generating commit message from OpenAI...")
commit_message = openai_provider.improve_text(prompt, diff)
if not commit_message:
print("No commit message generated. Aborting commit.")
return
# Step 6: Handle --print argument
if args.print:
print(f"Commit message (not committing): {commit_message}")
return
# Step 7: Create the commit with the message from OpenAI
print(f"Committing with message: {commit_message}")
# Run git commit and suppress interactive editor
result = subprocess.run(
["git", "commit", "-m", commit_message],
check=True,
cwd=cwd,
stdin=subprocess.DEVNULL, # Prevents editor from being opened
stdout=subprocess.PIPE, # Captures stdout to prevent blocking
stderr=subprocess.PIPE # Captures stderr to prevent blocking
)
# Print the result of the commit
print(f"Commit successful! {result.stdout.decode('utf-8')}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment