Skip to content

Instantly share code, notes, and snippets.

@laurentperrinet
Forked from fritzprix/llm-commit.sh
Last active January 12, 2026 16:19
Show Gist options
  • Select an option

  • Save laurentperrinet/176591df03d272fa7a2d14892c4a2622 to your computer and use it in GitHub Desktop.

Select an option

Save laurentperrinet/176591df03d272fa7a2d14892c4a2622 to your computer and use it in GitHub Desktop.
🤖 Generate git commit messages automatically using local LLM (Ollama). Simple bash script that analyzes your git diff and creates meaningful commit messages. Runs locally with Ollama.
#!/bin/bash
OLLAMA_MODEL="gpt-oss:120b-cloud"
ASK_PULL=false
ASK_PUSH=false
TARGETS=()
show_help() {
cat <<EOF
An auto-commit tool in bash using Ollama
https://gist.github.com/laurentperrinet/176591df03d272fa7a2d14892c4a2622
Usage: $(basename "$0") [options] [path1] [path2] ...
Options:
-a, --ask-pull Ask before running 'git pull' (interactive)
-p, --ask-push Ask before running 'git push' (interactive)
-m, --model <name> Use a specific Ollama model (default: gpt-oss:120b-cloud)
-h, --help Show this help and exit
If one or more paths are provided, only those paths will be staged and committed.
If no paths are given, the script keeps the original behavior (git add -u).
If --ask-pull is not given, the script runs 'git pull' automatically.
EOF
}
# Parse args: optional flags and one or more paths
while [[ $# -gt 0 ]]; do
case "$1" in
-a|--ask-pull) ASK_PULL=true; shift ;;
-p|--ask-push) ASK_PUSH=true; shift ;;
# NEW: Parse the --model flag and its argument
-m|--model)
if [[ -n "$2" ]]; then
OLLAMA_MODEL="$2"
shift 2 # Consume the flag and its argument
else
echo "Error: --model requires a model name as an argument."
show_help
exit 1
fi
;;
-h|--help) show_help; exit 0 ;;
--) shift; break ;;
-*)
echo "Unknown option: $1"
show_help
exit 1
;;
*)
# Append all non-flag arguments to the TARGETS array.
TARGETS+=("$1")
shift
;;
esac
done
if [[ "$ASK_PULL" == "true" ]]; then
echo -e "\nShould I git pull first? (Y/n)"
read answer
if [[ -z "$answer" || "$answer" =~ ^[Yy]$ ]]; then
git pull
fi
else
echo "Running 'git pull' (no prompt)..."
git pull
fi
# MODIFICATION: The staging logic is updated to handle multiple paths.
# It checks if the TARGETS array has any elements.
if [[ ${#TARGETS[@]} -gt 0 ]]; then
echo "Staging specified paths: ${TARGETS[*]}"
# -A ensures new, modified and deleted files under the paths are staged.
# "${TARGETS[@]}" correctly expands the array, handling filenames with spaces.
git add -A -- "${TARGETS[@]}"
else
echo "Staging all modified/deleted files (git add -u)..."
git add -u
fi
git diff --cached > /tmp/git_diff.txt
# If there's no diff, exit
if [ ! -s /tmp/git_diff.txt ]; then
echo "No staged changes to commit"
exit 1
fi
cat /tmp/git_diff.txt
# Create the prompt with the diff content, escaping special characters
diff_content=$(sed 's/"/\\"/g; s/\\/\\\\/g; s/`/\\`/g' /tmp/git_diff.txt)
prompt="You are a scientific pragrammer writing code in computational neuroscience, artificial intelligence and machine learning. Given the following git diff, write a clear and concise git commit message that summarizes the changes.\n\nREQUIREMENTS:\n- Focus on WHAT changed and WHY. Use present tense, imperative mood. Keep it under 72 characters for the first line, then add more details after a blank line. Use present tense, imperative mood ('Add', 'Fix', 'Update', not 'Added', 'Fixed'). Remember to keep the first line under 72 characters\n- Focus exclusively on WHAT changed and WHY\n- Do not add opinions, suggestions for improvements, or commentary beyond the changes shown\n- Detect and explicitly mention file operations: renames, deletions, moves, additions\n- Add detail after a blank line only if necessary to explain the context of the changes\n\nFORMAT:\n[Action] [Subject] - [File operations if applicable]\n\n[Optional detailed explanation of WHY these changes were made]\n\nFILE OPERATIONS TO DETECT:\n- File renamed: 'Rename X to Y'\n- File deleted: 'Remove X'\n- File moved: 'Move X from A to B'\n- Multiple files: 'Refactor module files: rename handler.js, move utils.js'\n\nOUTPUT ONLY THE COMMIT MESSAGE. DO NOT INCLUDE ANY OTHER TEXT, ANALYSIS, OR RECOMMENDATIONS. DO NOT WRITE ANYTHING LONGER THAN 5000 WORDS. \n\nGIT DIFF:\n\n$diff_content"
# Run the prompt through ollama and save the response
ollama run "$OLLAMA_MODEL" --hidethinking "$prompt" > /tmp/commit_msg.txt
# Show the proposed commit message and ask for confirmation
echo -e "\nProposed commit message:"
echo "------------------------"
cat /tmp/commit_msg.txt
echo "------------------------"
echo -e "\nDo you want to proceed with this commit message? (Y/n)"
read answer
if [[ -z "$answer" || "$answer" =~ ^[Yy]$ ]]; then
# Perform the commit using the generated message
git commit -F /tmp/commit_msg.txt
echo "Changes committed successfully!"
else
echo "Commit canceled"
fi
# Clean up temporary files
rm /tmp/git_diff.txt /tmp/commit_msg.txt
if [[ "$ASK_PUSH" == "true" ]]; then
echo -e "\nShould I git push now? (Y/n)"
read answer
if [[ -z "$answer" || "$answer" =~ ^[Yy]$ ]]; then
git push
fi
else
echo "Running 'git push' (no prompt)..."
git push
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment