-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathgit-commit.sh
executable file
·183 lines (157 loc) · 4.94 KB
/
git-commit.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#!/bin/bash
CONFIG_DIR="$HOME/.config/git-commit-ai"
CONFIG_FILE="$CONFIG_DIR/config"
# Debug mode flag
DEBUG=false
# Push flag
PUSH=false
# Model selection
MODEL="google/gemini-flash-1.5-8b"
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
--debug)
DEBUG=true
shift
;;
--push | -p)
PUSH=true
shift
;;
--model)
# Check if next argument exists and doesn't start with -
if [[ -n "$2" && "$2" != -* ]]; then
MODEL="$2"
shift 2
else
echo "Error: --model requires a valid model name"
exit 1
fi
;;
*)
API_KEY_ARG="$1"
shift
;;
esac
done
# Debug function
debug_log() {
if [ "$DEBUG" = true ]; then
echo "DEBUG: $1"
if [ ! -z "$2" ]; then
echo "DEBUG: Content >>>"
echo "$2"
echo "DEBUG: <<<"
fi
fi
}
debug_log "Script started"
debug_log "Config directory: $CONFIG_DIR"
# Create config directory if it doesn't exist
mkdir -p "$CONFIG_DIR"
chmod 700 "$CONFIG_DIR"
debug_log "Config directory created/checked"
# Function to save API key
save_api_key() {
echo "$1" >"$CONFIG_FILE"
chmod 600 "$CONFIG_FILE"
debug_log "API key saved to config file"
}
# Function to get API key
get_api_key() {
if [ -f "$CONFIG_FILE" ]; then
cat "$CONFIG_FILE"
else
echo ""
fi
}
# Check if API key is provided as argument or exists in config
if [ ! -z "$API_KEY_ARG" ]; then
debug_log "New API key provided as argument"
save_api_key "$API_KEY_ARG"
fi
API_KEY=$(get_api_key)
debug_log "API key retrieved from config"
if [ -z "$API_KEY" ]; then
echo "No API key found. Please provide the OpenRouter API key as an argument"
echo "Usage: ./git-commit.sh [--debug] [--push|-p] [--model <model_name>] <api_key>"
exit 1
fi
# Stage all changes
debug_log "Staging all changes"
git add .
# Get git changes
CHANGES=$(git diff --cached --name-status)
debug_log "Git changes detected" "$CHANGES"
if [ -z "$CHANGES" ]; then
echo "No staged changes found. Please stage your changes using 'git add' first."
exit 1
fi
# Prepare the request body
REQUEST_BODY=$(
cat <<EOF
{
"stream": false,
"model": "$MODEL",
"messages": [
{
"role": "system",
"content": "Provide a detailed commit message with a title and description. The title should be a concise summary (max 50 characters). The description should provide more context about the changes, explaining why the changes were made and their impact. Use bullet points if multiple changes are significant. If it's just some minor changes, use 'fix' instead of 'feat'. Do not include any explanation in your response, only return a commit message content, do not wrap it in backticks"
},
{
"role": "user",
"content": "Generate a commit message in conventional commit standard format based on the following file changes:\n\`\`\`\n${CHANGES}\n\`\`\`\n- Commit message title must be a concise summary (max 100 characters)\n- If it's just some minor changes, use 'fix' instead of 'feat'\n- IMPORTANT: Do not include any explanation in your response, only return a commit message content, do not wrap it in backticks"
}
]
}
EOF
)
debug_log "Request body prepared with model: $MODEL" "$REQUEST_BODY"
# Make the API request
debug_log "Making API request to OpenRouter"
RESPONSE=$(curl -s -X POST "https://openrouter.ai/api/v1/chat/completions" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d "$REQUEST_BODY")
debug_log "API response received" "$RESPONSE"
# Extract and clean the commit message
# First, try to parse the response as JSON and extract the content
COMMIT_FULL=$(echo "$RESPONSE" | jq -r '.choices[0].message.content')
# If jq fails or returns null, fallback to grep method
if [ -z "$COMMIT_FULL" ] || [ "$COMMIT_FULL" = "null" ]; then
COMMIT_FULL=$(echo "$RESPONSE" | grep -o '"content":"[^"]*"' | cut -d'"' -f4)
fi
# Clean the message:
# 1. Preserve the structure of the commit message
# 2. Clean up escape sequences
COMMIT_FULL=$(echo "$COMMIT_FULL" |
sed 's/\\n/\n/g' |
sed 's/\\r//g' |
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' |
sed 's/\\[[:alpha:]]//g')
debug_log "Extracted commit message" "$COMMIT_FULL"
if [ -z "$COMMIT_FULL" ]; then
echo "Failed to generate commit message. API response:"
echo "$RESPONSE"
exit 1
fi
# Execute git commit
debug_log "Executing git commit"
git commit -m "$COMMIT_FULL"
if [ $? -ne 0 ]; then
echo "Failed to commit changes"
exit 1
fi
# Push to origin if flag is set
if [ "$PUSH" = true ]; then
debug_log "Pushing to origin"
git push origin
if [ $? -ne 0 ]; then
echo "Failed to push changes"
exit 1
fi
echo "Successfully pushed changes to origin"
fi
echo "Successfully committed and pushed changes with message:"
echo "$COMMIT_FULL"
debug_log "Script completed successfully"