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.

Revisions

  1. dmzoneill created this gist Apr 11, 2025.
    114 changes: 114 additions & 0 deletions fancy-git-commit.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,114 @@
    #!/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()