Skip to content

Instantly share code, notes, and snippets.

@mikelane
Created February 27, 2024 22:20
Show Gist options
  • Save mikelane/ffa69a10e7fe166655390b70ceccf730 to your computer and use it in GitHub Desktop.
Save mikelane/ffa69a10e7fe166655390b70ceccf730 to your computer and use it in GitHub Desktop.
A script that sends the diff of staged files to shell-gpt so that it can create a nifty commit message.
#!/usr/bin/env bash
check_commands_available() {
local missing_cmds=()
local cmds=("sgpt" "pandoc") # Add any other required commands to this array
for cmd in "${cmds[@]}"; do
if ! command -v "$cmd" &> /dev/null; then
missing_cmds+=("$cmd")
fi
done
if [ ${#missing_cmds[@]} -ne 0 ]; then
echo "Error: The following required commands are not installed or not in the PATH:"
for cmd in "${missing_cmds[@]}"; do
echo "- $cmd"
done
exit 1
fi
}
generate_commit_message() {
check_commands_available
local diff_output_file="diff_output.txt"
local diff_lock_snap_file="diff_lock_snap.txt"
# Generate the diff files
git diff --cached origin/"$(git branch --show-current)" -- . ':(exclude)**/*lock.yaml' ':(exclude)**/*.lock' ':(exclude)*.snap' > "$diff_output_file"
git diff --cached origin/"$(git branch --show-current)" --name-only -- '**/*lock.yaml' '**/*.lock' '**/*.snap' > "$diff_lock_snap_file"
read -r -d '' SGPT_INSTRUCTIONS << EOF
Please generate a commit message from the included changes with the
following guidelines:
1. It should begin with a short (72 chars or less) summary
2. Following the summary, it should include more detailed explanatory
text. Please wrap the explanatory text to 72 characters. The blank
line separating the summary from the body is critical (unless you
omit the body entirely).
3. Write your commit message in the imperative, _e.g._, "Fix bug" and
not "Fixed bug" or "Fixes bug." This convention matches up with
commit messages generated by commands like git merge and git revert.
4. Any further paragraphs come after blank lines.
Note:
- Bullet points are okay, too.
- Typically a hyphen or asterisk is used for the bullet, followed by a
single space. Use a hanging indent.
Additionally:
- Configuration files like pyproject.toml, package.json, or Cargo.toml
generally should not be considered the primary change unless the rest
of the files are changed because they are fixing breaking changes in
a new dependency version.
- Changes in code files such as .py, .ts, .js, or .rs files should
generally be considered the primary changes and the changes that are
called out in the title and main body of the commit.
Please provide the output as plain text without any avoiding code fences
(triple backticks) around the response.
EOF
cat "$diff_output_file" "$diff_lock_snap_file" | sgpt "$SGPT_INSTRUCTIONS"
rm "$diff_output_file" "$diff_lock_snap_file"
}
commit_message=$(generate_commit_message | pandoc -f markdown -t markdown --wrap=auto --columns=72)
echo "$commit_message"
choice=$(fzf --height=10 --reverse --header="Select an action for the commit message:" <<EOF
Use this commit message
Edit this commit message
Cancel the commit
EOF
)
case $choice in
"Use this commit message")
git commit -m "$commit_message"
;;
"Edit this commit message")
git commit -m "$commit_message"
git commit --amend
;;
"Cancel the commit")
echo "Commit cancelled."
;;
*)
echo "Invalid choice. Commit cancelled."
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment