Scrivere messaggi di commit chiari e consistenti è una buona pratica, ma spesso la cosa che viene saltata quando si lavora velocemente e non si ha tempo e modo di scrivere il messaggio in modo articolato (oppure non in conventional style 😉).
Ho automatizzato questo passaggio tramite gcommit, una piccola funzione Bash che legge la staging area di Git e delega la generazione del messaggio a un LLM; il tutto direttamente dal terminale.
Il Problema e l’Idea

Un buon messaggio di commit dovrebbe rispettare una convenzione, descrivere cosa cambia e perché, e farlo in modo sintetico. Tutto questo richiede attenzione e tempo, risorse che a fine sessione di debug tendono a scarseggiare.
L’idea è semplice:
il git diff --cached contiene, quasi sempre, già tutta l’informazione necessaria per descrivere le modifiche. Perché non passarne l’output a un LLM chiedendo la generazione di un messaggio di commit fatto bene?
llm: LLM dalla Riga di Comando
llm è uno strumento CLI open-source sviluppato da Simon Willison (il co-creatore di Django) e parte del progetto Datasette. Permette di interagire con decine di modelli (OpenAI, Anthropic Claude, Google Gemini, etc) sia tramite API remote che in locale tramite plugin (es. llm-ollama).
L’utilizzo base è minimalista:
# Prompt semplice
llm "Spiega questo errore: segmentation fault"
# Pipe da stdin
cat myfile.py | llm -s "Spiega questo codice"
# Specifica un modello
llm -m claude-4-opus "Dimmi qualcosa sulle turnip"
È scritto in Python. L’installazione può quindi essere fatta direttamente tramite pip, pipx, uv:
pipx install llm # consigliato per isolare le dipendenze
uv tool install llm # consigliato per isolare le dipendenze
llm keys set openai # configura la chiave API
I Template in llm
llm supporta i template: file YAML riutilizzabili che combinano un system prompt, un modello di default e opzioni preconfigurate .
Un template viene invocato con il flag -t:
cat myfile.py | llm -t code-review
Per il workflow dei commit, ho creato un template chiamato git-commit:
llm templates edit git-commit
Il contenuto del template è il seguente:
Generate a commit message following the "Conventional Commits" standard.
Analyze the given git diff input.
Use this format:
`<type>(<scope>): <brief description>`
`<body of the message with technical explanation>`
Allowed types: feat, fix, docs, style, refactor, perf, test, chore.
Use english to generate di commit message, also if the codebase is in other language.
Ultimamente sto utilizzando DeepSeek. Ho settato su llm un alias e chiamo il modello con il parametro-m ds
Quindi, per esempio, lanciando:
llm -m ds -t git-commit "Testo di input"
sto dicendo a llm di utilizzare, sul testo di input fornito, il modello DeepSeek con il template git-commit.
La Funzione gcommit
La funzione può essere inserita nel .bashrc e si compone di tre passi logici:
gcommit() {
# 1. Controlla se ci sono file in stage
if git diff --cached --quiet; then
echo "⚠️ Nessun file in stage. Fai 'git add <files>' prima di lanciare gcommit."
return 1
fi
echo -e "🤖 \033[1;30mGenerazione del messaggio di commit in corso...\033[0m\n"
# 2. Passa il diff all'LLM usando il template git-commit
COMMIT_MSG=$(git diff --cached | llm -m ds -t git-commit)
# 3. Stampa il risultato in turchese
echo -e "\033[1;36m$COMMIT_MSG\033[0m\n"
}
Step 1 — Cerca le modifiche:
Staging vuoto → git diff –cached –quiet esce con 0 → la condizione è vera → viene stampato il warning e la funzione termina
Staging non vuoto → esce con 1 → la condizione è falsa → si prosegue con la generazione del messaggio
Step 2 — Generazione: git diff --cached produce il diff completo dei file in stage, che viene passato via pipe a llm. Il flag -m ds specifica il modello, -t git-commit applica il template con il system prompt.
Step 3 — Output: Il messaggio viene stampato in ciano bold (\033[1;36m) per distinguerlo visivamente dall’output normale del terminale.
Il messaggio non viene committato automaticamente.
Ma si può ovviamente pensare di evolvere lo script prevedendo anche il commit di quanto proposto.
Io, per ora, preferisco andare a mano.
Flusso di Utilizzo Tipico
L’utilizzo del tutto è semplice. Quando ho i file in staging lancio il comando gcommit e ottengo in automatico il messaggio che desideravo.
Esempio:
# 1. Modifica i file
nvim src/parser.py
# 2. Stage delle modifiche
git add src/parser.py
# 3. Genera il messaggio
gcommit
# → 🤖 Generazione del messaggio di commit in corso...
# → refactor(parser): extract token validation into separate method
# →
# → Move inline validation logic into `validate_token()` to improve
# → readability and allow independent unit testing.
# 4. Committa
git commit -m "refactor(parser): extract token validation into separate method bla bla bla"
Estensioni Possibili (suggerite dal mio llm)
- Auto-commit con conferma: aggiungere un
read -p "Confermi? [y/N] "e committare automaticamente se si rispondey - Modello configurabile: accettare un parametro opzionale per sovrascrivere il modello (
gcommit gpt-4o) - Supporto multi-lingua: parametrizzare la lingua del messaggio nel template
- Integrazione con
fzf: mostrare più proposte e scegliere interattivamente
Immagine copertina: The vaudeville star Fritzi Ridgeway, showing what it takes to melt a snowman (immagine colorizzata con AI)