Skip to content

Commit 573b36b

Browse files
committed
Refine aicommit with iterative subject Shortening
Two-Stage Commit Message Generation: First, generate a detailed commit description. Then, refine the subject line for conciseness and clarity. If the initial subject exceeds 50 characters, the script regenerates it with explicit length constraints. Up to 10 iterations ensure compliance with Git conventions. If still too long, a warning prompts users for manual adjustments. This commit also improved LLM instructions for better adherence to commit message best practices. Clear separation of Subject Line and Body with enforced constraints. Set SHOW_AI_COMMIT_PROMPT to see full prompt. Set TEMPERATURE to change model temperature. Change-Id: I6b9c1337210b86a400e84c3984c17dcdc72fb26e
1 parent b8a6fa9 commit 573b36b

File tree

2 files changed

+112
-6
lines changed

2 files changed

+112
-6
lines changed

scripts/aspell-pws

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,5 @@ noreturn
352352
pragma
353353
ollama
354354
qwen
355+
aicommit
356+
LLM

scripts/prepare-commit-msg.hook

Lines changed: 110 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,18 @@ EOF
3737
# AICommit uses an LLM (via ollama) to generate commit messages that match git
3838
# commit style by learning from previous commits.
3939
# Inspired by https://github.com/acrosa/aicommits.
40+
#
41+
# Configuration options:
42+
# - aicommit.temperature: Controls the randomness of the generated text (default: 0.3)
43+
# Example: git config --global aicommit.temperature 0.5
44+
# - aicommit.show-prompt: Show the full prompts used for generation (default: false)
45+
# Example: git config --global aicommit.show-prompt true
46+
# - core.aicommit: Control when to use AI commit ('always', 'auto', or 'never', default: 'auto')
47+
# Example: git config --global core.aicommit always
48+
4049
MODEL="qwen2.5-coder"
50+
TEMPERATURE=$(git config --get aicommit.temperature || echo 0.3)
51+
SHOW_AI_COMMIT_PROMPT=$(git config --get aicommit.show-prompt || echo "false")
4152
SUGGESTED_COMMITMSG=
4253
AICOMMIT=$(git config --get core.aicommit || echo 'auto')
4354
if [[ "$AICOMMIT" == "always" ]] || [[ "$AICOMMIT" == "auto" && -t 1 ]] && \
@@ -60,18 +71,21 @@ Analyze the following commit messages and produce **accurate, concise, and meani
6071
# Output:
6172
Provide a concise description of the style without quoting commit content.
6273
"
63-
echo "Running ollama... "
74+
echo "Running ollama to set temperature to $TEMPERATURE (You can set aicommit.temperature git config to change it)"
75+
echo "/set parameter temperature $TEMPERATURE"
76+
echo "Running ollama for style analysis... (You can set aicommit.show-prompt git config to see full prompt)"
6477
style_description=$(echo "$style_prompt" | ollama run "$MODEL")
6578

6679
# Build the commit message prompt.
6780
prompt="
6881
# Context:
6982
Style: $style_description
7083
71-
# Instructions:
84+
# Instructions: Follow these carefully to generate a high-quality commit message. MUST be concise, style-consistent, and under length limits.
85+
86+
- Generate a commit message that consists of a Subject Line and a Body, separated by a blank line.
7287
- Analyze the diff below and generate a commit message based solely on its content.
73-
- Mimic the style described above (tone, length, structure) without copying previous messages.
74-
- Use clear action verbs and be concise.
88+
- **Crucially, mimic the style** described above (tone, length, structure) without copying previous messages. **Pay close attention to maintaining consistency with the established style.**- Use clear action verbs and be concise.
7589
- Output ONLY the commit message (subject, a blank line, then body).
7690
- Separate the subject from the body with a blank line.
7791
- Remove triple backticks; replace backticks with single quotes.
@@ -82,12 +96,15 @@ Style: $style_description
8296
- No concluding remarks.
8397
- Do NOT use conventional commit prefixes (like 'feat:', 'fix:', 'docs:')
8498
- Avoid the redundant message like 'Updated commit messages'
99+
- Directly output your commit message, without additional explanations.
100+
- Avoid using ### or other markdown formatting.
85101
86102
# Diff:
87103
<diff>$staged_diff</diff>
88104
89105
Commit message:"
90-
if [ "$2" = "--show-prompt" ]; then
106+
# Show prompts if aicommit.show-prompt is set to true
107+
if [ "$SHOW_AI_COMMIT_PROMPT" = "true" ]; then
91108
echo "Full style prompt:"
92109
echo "$style_prompt"
93110
echo "Extracted style:"
@@ -97,15 +114,102 @@ Commit message:"
97114
fi
98115

99116
# Generate commit message using ollama.
117+
echo "Running ollama for commit message... "
100118
SUGGESTED_COMMITMSG=$(echo "$prompt" | ollama run "$MODEL")
101119

102120
# Post-process the commit message.
103121
# - Trim whitespace.
104122
# - Remove triple backticks.
105123
# - Replace backticks with single quotes.
106-
# - Wrap lines at 72 characters.
107124
SUGGESTED_COMMITMSG=$(echo "$SUGGESTED_COMMITMSG" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
108125
SUGGESTED_COMMITMSG=$(echo "$SUGGESTED_COMMITMSG" | sed -E '/^(Author:|Date:|Commit message:)/d')
126+
SUGGESTED_COMMITMSG=$(echo "$SUGGESTED_COMMITMSG" | sed -E '/^```(markdown|diff|text|plaintext)?$/d; s/\*\*([^*]+)\*\*/\1/g; s/`([^`]+)`/'\''\1'\''/g')
127+
128+
# Extract the subject line (first line) and body
129+
subject_line=$(echo "$SUGGESTED_COMMITMSG" | head -n 1)
130+
body=$(echo "$SUGGESTED_COMMITMSG" | tail -n +3) # Skip the first line and the blank line
131+
132+
# Check if the subject line is too long
133+
if [ ${#subject_line} -gt 50 ]; then
134+
echo "Subject line too long (${#subject_line} chars), will attempt to regenerate up to 10 times..."
135+
136+
# Try up to 10 times to generate a subject line under 50 characters
137+
max_attempts=10
138+
attempt=1
139+
original_subject="$subject_line"
140+
141+
while [ $attempt -le $max_attempts ] && [ ${#subject_line} -gt 50 ]; do
142+
echo "Attempt $attempt of $max_attempts to generate a shorter subject line..."
143+
144+
# Generate a new subject line based on the body and previous attempts
145+
subject_prompt="
146+
# Context
147+
Original subject (${#original_subject} chars):
148+
$original_subject
149+
150+
Previous attempt (${#subject_line} chars):
151+
$subject_line
152+
153+
Body:
154+
$body
155+
156+
# Instructions:
157+
- The previous commit message's subject line was too long, exceeding 50 characters. Your task is to shorten it to 50 characters or less.
158+
- Based on this commit message, create ONLY a subject line for the commit message
159+
- The subject line MUST be under 50 characters (this is attempt $attempt of $max_attempts)
160+
- Use imperative mood (e.g., 'Add' not 'Added')
161+
- Capitalize the first word
162+
- Do not end with a period
163+
- Be specific but concise
164+
- Use clear action verbs
165+
- Avoid vague terms like 'Update' or 'Fix' without context
166+
- Output ONLY the subject line, nothing else
167+
- Do NOT use conventional commit prefixes (like 'feat:', 'fix:', 'docs:')
168+
- Use plain text without markdown or HTML
169+
170+
# Output:"
171+
172+
echo "Running ollama for new subject line (attempt $attempt)... "
173+
new_subject_line=$(echo "$subject_prompt" | ollama run "$MODEL")
174+
175+
# Clean up the new subject line
176+
new_subject_line=$(echo "$new_subject_line" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
177+
new_subject_line=$(echo "$new_subject_line" | sed -E '/^(Author:|Date:|Subject line:)/d')
178+
new_subject_line=$(echo "$new_subject_line" | sed -E '/^```(markdown|diff|text|plaintext)?$/d; s/\*\*([^*]+)\*\*/\1/g; s/`([^`]+)`/'\''\1'\''/g')
179+
180+
# Update the subject line
181+
subject_line="$new_subject_line"
182+
183+
# Check if the new subject line is under 50 characters
184+
if [ ${#subject_line} -le 50 ]; then
185+
echo "Success! Generated a subject line under 50 characters (${#subject_line} chars)."
186+
break
187+
else
188+
echo "Attempt $attempt failed: Subject line still too long (${#subject_line} chars)."
189+
fi
190+
191+
attempt=$((attempt + 1))
192+
done
193+
194+
# If we've tried 3 times and still have a long subject line, inform the user
195+
if [ ${#subject_line} -gt 50 ]; then
196+
echo "Warning: After $max_attempts attempts, the subject line is still too long (${#subject_line} chars)."
197+
echo "You may want to edit it manually to comply with the 50-character limit."
198+
fi
199+
fi
200+
201+
# Combine the (possibly new) subject line with the original body
202+
SUGGESTED_COMMITMSG="$subject_line
203+
204+
$body"
205+
206+
# Show final subject line if aicommit.show-prompt is set to true
207+
if [ "$SHOW_AI_COMMIT_PROMPT" = "true" ]; then
208+
echo "Final subject line (${#subject_line} chars):"
209+
echo "$subject_line"
210+
fi
211+
212+
# Wrap lines at 72 characters
109213
SUGGESTED_COMMITMSG="$(
110214
echo "$SUGGESTED_COMMITMSG" \
111215
| sed -E '/^```(markdown|diff|text|plaintext)?$/d; s/\*\*([^*]+)\*\*/\1/g; s/`([^`]+)`/'\''\1'\''/g' \

0 commit comments

Comments
 (0)