diff --git a/scripts/aspell-pws b/scripts/aspell-pws index 7b443ac9a..1094a19e9 100644 --- a/scripts/aspell-pws +++ b/scripts/aspell-pws @@ -352,3 +352,5 @@ noreturn pragma ollama qwen +aicommit +LLM diff --git a/scripts/prepare-commit-msg.hook b/scripts/prepare-commit-msg.hook index 2e6d5152c..7ab330d94 100755 --- a/scripts/prepare-commit-msg.hook +++ b/scripts/prepare-commit-msg.hook @@ -37,7 +37,18 @@ EOF # AICommit uses an LLM (via ollama) to generate commit messages that match git # commit style by learning from previous commits. # Inspired by https://github.com/acrosa/aicommits. +# +# Configuration options: +# - aicommit.temperature: Controls the randomness of the generated text (default: 0.3) +# Example: git config --global aicommit.temperature 0.5 +# - aicommit.show-prompt: Show the full prompts used for generation (default: false) +# Example: git config --global aicommit.show-prompt true +# - core.aicommit: Control when to use AI commit ('always', 'auto', or 'never', default: 'auto') +# Example: git config --global core.aicommit always + MODEL="qwen2.5-coder" +TEMPERATURE=$(git config --get aicommit.temperature || echo 0.3) +SHOW_AI_COMMIT_PROMPT=$(git config --get aicommit.show-prompt || echo "false") SUGGESTED_COMMITMSG= AICOMMIT=$(git config --get core.aicommit || echo 'auto') if [[ "$AICOMMIT" == "always" ]] || [[ "$AICOMMIT" == "auto" && -t 1 ]] && \ @@ -60,7 +71,9 @@ Analyze the following commit messages and produce **accurate, concise, and meani # Output: Provide a concise description of the style without quoting commit content. " - echo "Running ollama... " + echo "Running ollama to set temperature to $TEMPERATURE (You can set aicommit.temperature git config to change it)" + echo "/set parameter temperature $TEMPERATURE" + echo "Running ollama for style analysis... (You can set aicommit.show-prompt git config to see full prompt)" style_description=$(echo "$style_prompt" | ollama run "$MODEL") # Build the commit message prompt. @@ -68,10 +81,11 @@ Provide a concise description of the style without quoting commit content. # Context: Style: $style_description -# Instructions: +# Instructions: Follow these carefully to generate a high-quality commit message. MUST be concise, style-consistent, and under length limits. + +- Generate a commit message that consists of a Subject Line and a Body, separated by a blank line. - Analyze the diff below and generate a commit message based solely on its content. -- Mimic the style described above (tone, length, structure) without copying previous messages. -- Use clear action verbs and be concise. +- **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. - Output ONLY the commit message (subject, a blank line, then body). - Separate the subject from the body with a blank line. - Remove triple backticks; replace backticks with single quotes. @@ -82,12 +96,15 @@ Style: $style_description - No concluding remarks. - Do NOT use conventional commit prefixes (like 'feat:', 'fix:', 'docs:') - Avoid the redundant message like 'Updated commit messages' +- Directly output your commit message, without additional explanations. +- Avoid using ### or other markdown formatting. # Diff: $staged_diff Commit message:" - if [ "$2" = "--show-prompt" ]; then + # Show prompts if aicommit.show-prompt is set to true + if [ "$SHOW_AI_COMMIT_PROMPT" = "true" ]; then echo "Full style prompt:" echo "$style_prompt" echo "Extracted style:" @@ -97,15 +114,102 @@ Commit message:" fi # Generate commit message using ollama. + echo "Running ollama for commit message... " SUGGESTED_COMMITMSG=$(echo "$prompt" | ollama run "$MODEL") # Post-process the commit message. # - Trim whitespace. # - Remove triple backticks. # - Replace backticks with single quotes. - # - Wrap lines at 72 characters. SUGGESTED_COMMITMSG=$(echo "$SUGGESTED_COMMITMSG" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//') SUGGESTED_COMMITMSG=$(echo "$SUGGESTED_COMMITMSG" | sed -E '/^(Author:|Date:|Commit message:)/d') + SUGGESTED_COMMITMSG=$(echo "$SUGGESTED_COMMITMSG" | sed -E '/^```(markdown|diff|text|plaintext)?$/d; s/\*\*([^*]+)\*\*/\1/g; s/`([^`]+)`/'\''\1'\''/g') + + # Extract the subject line (first line) and body + subject_line=$(echo "$SUGGESTED_COMMITMSG" | head -n 1) + body=$(echo "$SUGGESTED_COMMITMSG" | tail -n +3) # Skip the first line and the blank line + + # Check if the subject line is too long + if [ ${#subject_line} -gt 50 ]; then + echo "Subject line too long (${#subject_line} chars), will attempt to regenerate up to 10 times..." + + # Try up to 10 times to generate a subject line under 50 characters + max_attempts=10 + attempt=1 + original_subject="$subject_line" + + while [ $attempt -le $max_attempts ] && [ ${#subject_line} -gt 50 ]; do + echo "Attempt $attempt of $max_attempts to generate a shorter subject line..." + + # Generate a new subject line based on the body and previous attempts + subject_prompt=" +# Context +Original subject (${#original_subject} chars): +$original_subject + +Previous attempt (${#subject_line} chars): +$subject_line + +Body: +$body + +# Instructions: +- The previous commit message's subject line was too long, exceeding 50 characters. Your task is to shorten it to 50 characters or less. +- Based on this commit message, create ONLY a subject line for the commit message +- The subject line MUST be under 50 characters (this is attempt $attempt of $max_attempts) +- Use imperative mood (e.g., 'Add' not 'Added') +- Capitalize the first word +- Do not end with a period +- Be specific but concise +- Use clear action verbs +- Avoid vague terms like 'Update' or 'Fix' without context +- Output ONLY the subject line, nothing else +- Do NOT use conventional commit prefixes (like 'feat:', 'fix:', 'docs:') +- Use plain text without markdown or HTML + +# Output:" + + echo "Running ollama for new subject line (attempt $attempt)... " + new_subject_line=$(echo "$subject_prompt" | ollama run "$MODEL") + + # Clean up the new subject line + new_subject_line=$(echo "$new_subject_line" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//') + new_subject_line=$(echo "$new_subject_line" | sed -E '/^(Author:|Date:|Subject line:)/d') + new_subject_line=$(echo "$new_subject_line" | sed -E '/^```(markdown|diff|text|plaintext)?$/d; s/\*\*([^*]+)\*\*/\1/g; s/`([^`]+)`/'\''\1'\''/g') + + # Update the subject line + subject_line="$new_subject_line" + + # Check if the new subject line is under 50 characters + if [ ${#subject_line} -le 50 ]; then + echo "Success! Generated a subject line under 50 characters (${#subject_line} chars)." + break + else + echo "Attempt $attempt failed: Subject line still too long (${#subject_line} chars)." + fi + + attempt=$((attempt + 1)) + done + + # If we've tried 3 times and still have a long subject line, inform the user + if [ ${#subject_line} -gt 50 ]; then + echo "Warning: After $max_attempts attempts, the subject line is still too long (${#subject_line} chars)." + echo "You may want to edit it manually to comply with the 50-character limit." + fi + fi + + # Combine the (possibly new) subject line with the original body + SUGGESTED_COMMITMSG="$subject_line + +$body" + + # Show final subject line if aicommit.show-prompt is set to true + if [ "$SHOW_AI_COMMIT_PROMPT" = "true" ]; then + echo "Final subject line (${#subject_line} chars):" + echo "$subject_line" + fi + + # Wrap lines at 72 characters SUGGESTED_COMMITMSG="$( echo "$SUGGESTED_COMMITMSG" \ | sed -E '/^```(markdown|diff|text|plaintext)?$/d; s/\*\*([^*]+)\*\*/\1/g; s/`([^`]+)`/'\''\1'\''/g' \