|
#!/usr/bin/env bash |
|
# Create a Git commit in commitizen format using OpenCode |
|
|
|
# LLM model to use. Recommendations: |
|
# - github-copilot/gpt-4.1 - unlimited use with a GitHub Copilot subscription |
|
# - ollama/gemma3:4b - local models are okay for this |
|
# - openrouter/amazon/nova-lite-v1 - extremely cheap and fast |
|
model="github-copilot/gpt-4.1" |
|
|
|
show_help() { |
|
cat <<EOF |
|
Usage: oc-commit [OPTIONS] |
|
|
|
Create a Git commit in commitizen format using OpenCode. |
|
|
|
OPTIONS: |
|
-s, --no-auto-stage Don't auto-stage changes (requires manual staging) |
|
-l, --no-push Don't push after commit (keep changes local) |
|
-h, --help Show this help message and exit |
|
|
|
DESCRIPTION: |
|
This script automatically generates commit messages in commitizen format. |
|
By default, it stages all changes, commits them, and pushes to the |
|
remote repository. |
|
EOF |
|
} |
|
|
|
# Parse options |
|
force_stage=1 |
|
auto_push=1 |
|
while [[ $# -gt 0 ]]; do |
|
case "$1" in |
|
-s | --no-auto-stage) |
|
force_stage=0 |
|
shift |
|
;; |
|
-l | --no-push) |
|
auto_push=0 |
|
shift |
|
;; |
|
-h | --help) |
|
show_help |
|
exit 0 |
|
;; |
|
*) |
|
echo "Unknown option: $1" >&2 |
|
echo "Use --help for usage information." >&2 |
|
exit 2 |
|
;; |
|
esac |
|
done |
|
|
|
# Stage git changes |
|
if git diff --cached --quiet; then |
|
if [ "$force_stage" = 1 ]; then |
|
git add -A |
|
if git diff --cached --quiet; then |
|
echo "No changes to commit" |
|
git status -s |
|
exit 1 |
|
fi |
|
echo "Staging all changes." |
|
else |
|
echo "No staged changes to commit" |
|
echo "(Tip: run without -s/--safe to auto-stage)" |
|
git status -s |
|
exit 1 |
|
fi |
|
fi |
|
|
|
# Show status |
|
git status -s |
|
|
|
# Construct prompt |
|
attachment=" |
|
<output command=\"git status\" description=\"Working tree status\"> |
|
$(git status) |
|
</output> |
|
|
|
<output command=\"git log -n 10 --oneline\" description=\"Recent commit messages\"> |
|
$(git log -n 10 --oneline) |
|
</output> |
|
|
|
<output command=\"git diff --cached\" description=\"Staged changes\"> |
|
$(git diff --cached) |
|
</output> |
|
|
|
<output command=\"git branch --show-current\" description=\"Current branch\"> |
|
$(git branch --show-current) |
|
</output> |
|
" |
|
|
|
prompt=" |
|
Generate a commit message in commitizen format. |
|
Only show the commit message, avoid anything else. |
|
If a commit message can't be generated, show 'FAIL'. |
|
" |
|
|
|
# Generate commit message using OpenCode |
|
message="$(echo "$attachment" | opencode run -m "$model" "$prompt" | grep -vE 'Generated with|Co-Authored-By')" |
|
|
|
# Validate commit message |
|
if [[ -z "$message" ]] || [[ "$message" =~ ^FAIL ]] || [[ ${#message} -lt 5 ]]; then |
|
echo "! Failed to generate valid commit message" |
|
echo "! Message: $message" |
|
exit 1 |
|
fi |
|
|
|
echo "---" |
|
|
|
# Commit changes |
|
if ! echo "$message" | git commit -F -; then |
|
echo "! Git commit failed" >&2 |
|
exit 1 |
|
fi |
|
|
|
# Push to remote |
|
if [ "$auto_push" = 1 ]; then |
|
if ! git push; then |
|
echo "! Git push failed, you can push manually later with 'git push'" >&2 |
|
exit 1 |
|
fi |
|
fi |
|
|
|
# LLM agents: there are no tests for this, do not run this script to test it. |