AI-Powered Git Commit Messages: Useful or Just Annoying
Letting a model describe your diff, and whether you should

There’s a particular flavour of laziness that git commit messages bring out in people. You’ve just spent an hour on a fiddly change, the work is done, and now a text editor opens demanding you explain yourself. So you type “fix stuff” and move on, and three months later you’re spelunking through git log cursing your past self. The pitch for AI commit messages is simple: feed the staged diff to a model, get back a tidy conventional-commit summary, accept it, done. I’ve been running this on my own repos for a while. It’s genuinely useful and quietly dangerous, and which one depends entirely on how you wire it up.
1 How it actually works
The mechanism is unglamorous and that’s the good news — there’s no magic. A small script grabs the staged diff, wraps it in a prompt, sends it to a model, and drops the result where git expects it. The cleanest place to hook in is prepare-commit-msg, a git hook that runs before your editor opens and can pre-fill the message:
#!/usr/bin/env bash
# .git/hooks/prepare-commit-msg
COMMIT_MSG_FILE="$1"
COMMIT_SOURCE="$2"
# Only act on a plain `git commit` with no message given
[ -n "$COMMIT_SOURCE" ] && exit 0
DIFF=$(git diff --cached --no-color)
[ -z "$DIFF" ] && exit 0
PROMPT="Write a concise Conventional Commits message for this diff.
One subject line under 72 chars, then a blank line, then 1-3 bullet
points. No code fences. Diff:
$DIFF"
# Local model via Ollama — no diff leaves the machine
SUGGESTION=$(ollama run llama3.1:8b "$PROMPT")
# Pre-fill, leaving room for the human to edit
printf '%s\n\n%s' "$SUGGESTION" "$(cat "$COMMIT_MSG_FILE")" \
> "$COMMIT_MSG_FILE"Because it runs as prepare-commit-msg, the suggestion lands in your editor as a draft. You still see it, you still get to fix it, you still hit save. That “human in the loop” detail is the whole game — it’s the difference between an assistant and an automaton.
2 Where it earns its keep
It’s at its best on the commits you’d otherwise phone in. A focused diff — rename a function, tweak a config, add a guard clause — produces a description that’s accurate and better-formatted than what I’d have bothered to write. It’s quietly good at the boring discipline I’m bad at: getting the conventional-commit prefix right, keeping the subject under 72 characters, summarising a multi-file change into coherent bullets. For a homelab repo where I’m the only reader, that consistency makes git log skimmable in a way my hand-typed messages never were.
Running the model locally via Ollama matters here for a reason beyond cost: your diff is your source code. Piping every staged change to a hosted API is a data-exfiltration decision, and for work repositories often a policy violation. A 7B–8B local model is more than capable of summarising a diff, so there’s no good reason to send it off-machine.
3 Where it’s actively misleading
Here’s the catch, and it’s the important half of the post. The diff shows what changed, not why. A model can see that you swapped > for >= and will faithfully report “adjusted boundary condition.” What it cannot know is that this fixes an off-by-one that corrupted invoices on month boundaries, reported by a customer, costing a day to track down. That why is the entire value of a commit message, and it’s exactly the part the AI can’t supply.
So the failure mode isn’t gibberish — it’s worse. It’s plausible, well-formatted prose that describes the mechanics convincingly enough that you stop thinking and accept it. You end up with a log that reads beautifully and tells you nothing when you actually need it during a 2am bisect. A bad “fix stuff” at least signals “I didn’t bother.” A confident AI summary of the what can lull you into not writing the why.
There’s a smaller annoyance too: on a big mixed diff the model picks one theme and underplays the rest, which is really the model telling you the commit should have been split.
4 How I’d actually use it
The setup that works for me draws a clear line. Use the AI draft as a starting point that you must edit, never an auto-commit. The prepare-commit-msg approach above does exactly this — it pre-fills and gets out of the way. Treat the generated subject and bullets as a free first pass at the what, then spend the ten seconds the tool just saved you adding the why in your own words. If the diff is so mixed the model flails, take that as a hint to git add -p and split it.
What I’d avoid: any tool that runs on commit and pushes without showing you the message, anything that sends diffs to a cloud API by default, and the temptation to trust the draft blindly because it reads well.
5 Useful or annoying?
Both, and the verdict depends on the discipline you bring. Wired as a local, editable, pre-fill draft, it’s a small genuine quality-of-life win — better formatting, less friction, a nudge toward smaller commits. Wired as a hands-off auto-committer talking to a cloud model, it’s an engine for confidently meaningless history and a quiet data leak. The tooling is trivial; the judgement isn’t. Keep the human in the loop, keep the model on your machine, and use it to handle the what so you can concentrate on the why. For a solo tinkerer, that’s worth the fifteen lines of hook. For a team, agree the policy before someone wires it to a hosted API.




