# git-lazy-commit

git-lazy-commit generates commit messages for staged changes in a git repository using OpenAI's OpenGPT.

This works surpisingly well, and I've used it for most of the commit messages in this repo (see Examples below).

Please beware that this tool is great at describing what you did, but not why you did it. I'd advise you to use it as a starting point, but then add the *why*.

## Installation

You can install the ChatGPT Commit Assistant using pip: `pip install git-lazy-commit`

You can upgrade it using `pip install --upgrade git-lazy-commit`.

## Usage

After staging some changes, call `git-lazy-commit`. It will generate a commit message for the staged changes. (By "staged changes", I mean the changes that you have run `git add` on, but not yet committed, i.e. the ones returned by `git diff --staged`.)

It will look for `OPENAI_API_KEY` in your environment variables. You can create keys at https://platform.openai.com/account/api-keys.

For example:

```
$ cd my-git-repo
$ git-lazy-commit
Generated commit message: Update example feature
Do you approve this commit message? (yes/no):
```

You can then respond with "yes" or "no". If you respond with "no", the script will generate a new commit message and ask for approval again. If you want to exit the script, you can press Ctrl+C.

You can pass the model you want to use using `-m/--model`, e.g. `-m gpt-4`. The default is `gpt-3-turbo`. Note that gpt-4 is quite a bit slower and more expensive. `gpt-3-turbo`, on the other hand, is extremely cheap (it's costing me less than 10 cents a day to use this).

You can also pass `--verbose` to see some extra info. For now it prints the token usage.

## Acknowledgement

It should not be surprising that this tool was itself mostly generated by ChatGPT (the GPT-4 version), except for `chatbot.py`, which was written by Simon Willison and discussed in [this blog post](https://til.simonwillison.net/gpt3/chatgpt-api).

## Examples
```diff
diff --git a/assistant/core.py b/assistant/core.py
index bea132e..7524ed4 100755
--- a/assistant/core.py
+++ b/assistant/core.py
@@ -1,6 +1,7 @@
 import os
-import git
 import argparse
+import subprocess
+import git
 from .chatbot import ChatBot


@@ -11,8 +12,9 @@ class Assistant:
             model=model,
         )

-    def get_uncommitted_changes(self, repo):
-        uncommitted_changes = repo.git.diff().split("\n")
+    def get_uncommitted_changes(self):
+        staged_changes = subprocess.run(["git", "diff", "--staged"], capture_output=True, text=True)
+        uncommitted_changes = staged_changes.stdout.split('\n')
         return uncommitted_changes

     def generate_commit_message(self, changes_summary):
@@ -47,7 +49,7 @@ def main(args=None):
     assistant = Assistant(args.model)

     repo = git.Repo(os.getcwd())
-    uncommitted_changes = assistant.get_uncommitted_changes(repo)
+    uncommitted_changes = assistant.get_uncommitted_changes()
     changes_summary = "\n".join(uncommitted_changes)
     generated_commit_message = assistant.generate_commit_message(changes_summary)
```

what I'd have written if I wasn't lazy: Use subprocess to call `git diff --staged` instead of trying to get gitpython to print what I want

gpt-3.5-turbo output: Refactored uncommitted changes retrieval to use subprocess instead of git module

gpt-4 output: Replaced gitpython with subprocess for getting staged changes and updated Assistant class methods accordingly

```diff
diff --git a/assistant/core.py b/assistant/core.py
index 7524ed4..d5a7a28 100755
--- a/assistant/core.py
+++ b/assistant/core.py
@@ -14,7 +14,7 @@ class Assistant:

     def get_uncommitted_changes(self):
         staged_changes = subprocess.run(["git", "diff", "--staged"], capture_output=True, text=True)
-        uncommitted_changes = staged_changes.stdout.split('\n')
+        uncommitted_changes = staged_changes.stdout.strip().split('\n')
         return uncommitted_changes

     def generate_commit_message(self, changes_summary):
```

what I'd have written if I wasn't lazy: Strip trailing whitespace because it breaks a test otherwise

gpt-3.5-turbo output: Fix parsing of staged changes output to remove empty line.

gpt-4 output: Improved parsing of uncommitted changes output

## License

Apache 2.0
