Last active
September 28, 2024 19:27
-
-
Save knyazer/675e6eb945ae5ec64af2f9be4826b07e to your computer and use it in GitHub Desktop.
Bringing AI to Git commit.
This file contains 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
function gcm | |
# Check if llm is installed, if not, install it | |
if not type -q llm | |
echo "'llm' is not installed. Attempting to install it using pip..." | |
if pip install llm | |
echo "'llm' installed successfully." | |
else | |
echo "Failed to install 'llm'. Please install it manually and try again." | |
return 1 | |
end | |
end | |
# Check if an API key is set up for llm | |
set llm_keys (llm keys) | |
if test "$llm_keys" = "No keys found" | |
echo "No API key found for 'llm'. You need to set it up." | |
llm keys set openai | |
if test $status -ne 0 | |
echo "Failed to set up the OpenAI key. Please try again manually." | |
return 1 | |
else | |
echo "OpenAI key set successfully." | |
end | |
end | |
# Function to generate commit message | |
function generate_commit_message | |
set -l prompt_text "Here are some examples of good commit messages: | |
- tests: correct TPU large array indexing tests | |
- feat: add overloads to eqx.combine | |
- docs: improve training loop documentation | |
- refactor: remove deprecated calls to jax.DeviceArray | |
- docs: explain why we do direct dtype conversion in precompute_freqs | |
- perf: donate tensors to increase memory utilization | |
- ci: switch from unittest to pytest | |
- tests: add double precision test for Adam | |
- build: allow cargo multithreading | |
- style: shorter conditions for key handling | |
- feat: partial weight decay only for weights | |
- refactor: improve control flow in some_model_function | |
- wip: debugging the flash attention with float16 | |
- style: fix the type annotations | |
- tests: add parametrized testing for the collision logic | |
Below is a diff of all changes coming from ```git diff HEAD```. Do NOT use quotes in your answer. Generate a concise, one-line, single sentence, at most 7 words long, summary commit message for these changes. End it with a new line, not a period. Feel free to provide a few-sentence explanation after a new line, so that it will be included as a commit description, but be as concise as possible! If it is taking more than 20 words, you are doing something wrong. | |
Prepend your answer with either of feat, fix, refactor, style, ci, docs, build, tests, perf, or wip, following the commitizen convention. The most important part to get right is the type of the commit, so make try as hard as possible to get it right! | |
Be specific, and make sure to mention only meaningful changes. Do not use generic terms, talk only about things that happened in the code. | |
\n\n" | |
# Check if --retry argument is present and get the index | |
set retry_index (contains --index -- '--retry' $argv) | |
if set -q $retry_index | |
set -l last_message $argv[$retry_index + 1] | |
echo "Previous message: $last_message" # For debugging purposes | |
set -l prompt_text "$prompt_text | |
The previous commit message generated was: | |
\`\`\` | |
$last_message | |
\`\`\` | |
It was not satisfactory. Below is the diff again. Please generate a better commit message. | |
Your answer must adhere to the commitizen convention." | |
end | |
git diff HEAD | llm $prompt_text | |
end | |
# Function to read user input | |
function read_input | |
set -l prompt $argv[1] | |
read -P $prompt reply | |
echo $reply | |
end | |
# Main script | |
if contains -- -a $argv | |
set files (git diff HEAD --name-only) | |
else | |
set files (git diff --cached --name-only) | |
echo "Generating AI-powered commit message for staged files:" | |
end | |
echo $files | |
set commit_message (generate_commit_message $argv --retry "") | |
while true | |
echo -e "Proposed commit message:\n" | |
echo $commit_message | |
echo -e "" | |
set choice (read_input "Do you want to (a)ccept or (r)egenerate? ") | |
set short_message (string split -m 1 "\n" $commit_message)[1] | |
set description (string split -m 1 "\n" $commit_message)[2] | |
if test -z "$description" | |
set description "" | |
end | |
switch $choice | |
case 'a' 'A' '' | |
if git commit $argv -m "$short_message" -m "$description" | |
echo "Changes committed successfully!" | |
return 0 | |
else | |
echo "Commit failed. Please check your changes and try again." | |
return 1 | |
end | |
case 'r' 'R' | |
echo "Regenerating commit message..." | |
set commit_message (generate_commit_message $argv --retry $commit_message) | |
case 'c' 'C' 'q' 'Q' | |
echo "Commit cancelled." | |
return 1 | |
case '*' | |
echo "Invalid choice. Please try again." | |
end | |
end | |
end |
@daanzu btw, I iterated on it quite a bunch, and the new version is a lot better; just updated it
Thanks for pinging, I completely forgot that I posted it here :)
Generally, just fixed some bugs, added more examples, allowed to write git commit description, and now it takes any arguments git commit
takes, which is nice; e.g. my workflow is
gcm -a && git push
and if I am too lazy I just press enter twice, so that it triggers automatic accept 😉
you can see some example commits I made with it at https://github.com/knyazer/nano_jax_gpt
@knyazer Neat changes; I'll try them out! FWIW, I had already made the following change, which is similar to yours but a different approach:
function generate_commit_message
set -l prompt_text "
Below is:
1. A list of recent git commit messages (just first lines), coming from the command:
\`\`\`
git log --oneline -n 20
\`\`\`
2. A diff of all staged changes, coming from the command:
\`\`\`
git diff --cached
\`\`\`
Please generate a concise, one-line commit message for these changes, using a similar format and styling as the existing commit messages. But really be concise! I mean it!"
if contains -- -a $argv
# git diff HEAD | llm $prompt_text
begin; echo "### GIT LOG ###"; git log --oneline -n 20; echo "### GIT DIFF ###"; git diff HEAD; end | llm $prompt_text
else
# git diff --cached | llm $prompt_text
begin; echo "### GIT LOG ###"; git log --oneline -n 20; echo "### GIT DIFF ###"; git diff --cached; end | llm $prompt_text
end
end
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for posting this!