Vai al contenuto principale

Guida completa ai Git Hook: installazione, utilizzo e consigli

Scopri come usare i Git hook per automatizzare attività, far rispettare gli standard di codice e mettere in sicurezza il tuo workflow con hook pre-commit, pre-push e lato server.
· 15 min leggi

Scopri con l'IA

I Git hook ti permettono di automatizzare attività nel tuo workflow eseguendo script prima o dopo azioni Git come commit o push. Aiutano a intercettare i problemi in anticipo, far rispettare gli standard e persino correggere automaticamente alcuni errori.

Mettiamo che tu abbia scritto uno script per far rispettare gli standard di stile del codice. Puoi aggiungerlo a un hook che viene eseguito prima di un commit. Ora, ogni volta che qualcuno prova a fare commit, l’hook parte. Se il codice supera i controlli nell’hook, il commit va a buon fine. Se non li supera, il commit viene bloccato.

E non si tratta solo di segnalare problemi. Puoi anche personalizzare lo script per correggere tali problemi prima che il commit avvenga. In questo articolo ti spiego tutto quello che devi sapere sui Git hook: cosa sono, quali contano davvero e come implementarli in modo efficace.

Cosa sono i Git Hook?

I Git hook eseguono automaticamente script personalizzati quando si verificano determinate azioni Git, ad esempio prima o dopo un commit, un push o un merge. Sono integrati in Git, quindi non serve installare librerie esterne.

Quando inizializzi un repository Git, Git crea gli hook di default. Li trovi nella directory .git/hooks. Hanno l’estensione .sample, che impedisce l’esecuzione di default. Se vuoi abilitarli, basta rimuovere l’estensione .sample.

Puoi scrivere gli hook in qualunque linguaggio di scripting eseguibile. Per esempio, dentro il file del pre-commit puoi aggiungere uno script che cerca commenti "To-do" nei file in stage e blocca il commit se ne trova. Significa che ogni volta che provi a fare commit, Git scansiona i commenti che iniziano con “To-do” e fallisce se ci sono attività in sospeso. Allo stesso modo puoi creare hook personalizzati per diverse azioni Git come post-commit, pre-merge, pre-push e altro.

Tipi di Git Hook

Prima di passare agli esempi pratici, capiamo le due tipologie di Git hook.

Hook lato client: categorie ed esempi comuni

Gli hook lato client vengono eseguiti sulle macchine locali durante le operazioni Git, come commit, rebase e push. Ecco alcuni hook client popolari e i loro casi d’uso specifici.

  • pre-commit: Viene eseguito prima ancora di digitare il messaggio di commit. Puoi usarlo per far rispettare gli stili di codice, eseguire test o controllare errori di sintassi prima del commit. 
  • prepare-commit-msg: Viene eseguito dopo che Git crea il messaggio di commit predefinito, ma prima che si apra l’editor del messaggio. Questo hook può modificare o sostituire il messaggio predefinito in base alla logica del tuo script. 
  • commit-msg: Questo hook parte subito dopo il salvataggio del messaggio di commit, ma prima che Git completi il commit. È l’ultimo checkpoint per far rispettare regole sul messaggio di commit come formattazione, struttura o tagging.
  • post-commit: Viene eseguito dopo la creazione di un commit. È spesso usato per notifiche (per esempio inviare un messaggio Slack dopo un commit) o per logging (salvare metadati del commit).
  • post-checkout: Viene eseguito dopo un comando git checkout riuscito. Si attiva quando cambi branch o fai checkout di uno specifico commit o percorso. Puoi usarlo per ricostruire le dipendenze del progetto, eliminare file temporanei o segnalare un nuovo branch.
  • post-merge: Viene eseguito dopo un merge riuscito. È comunemente usato per aggiornare le dipendenze, stampare messaggi di merge o svuotare le cache.
  • pre-rebase: Viene eseguito prima di un’operazione di rebase. Puoi usarlo per impedire il rebase di branch protetti, eseguire test prima di consentire il rebase o bloccarlo se ci sono modifiche non versionate.
  • pre-push: Viene eseguito prima di effettuare un push. Aiuta a impedire push su branch protetti o a eseguire test pre-push.
  • post-rewrite: Viene eseguito dopo che Git ha riscritto correttamente i commit. Si attiva su operazioni come git commit --amend (che riscrive l’ultimo commit) o git rebase (che riscrive una serie di commit). Usalo per aggiornare riferimenti o avviare test e step CI dopo la riscrittura.
  • pre-applypatch: Invocato dal comando git am, questo hook viene eseguito dopo che una patch è stata applicata alla working tree ma prima della creazione di un nuovo commit. Se i controlli in questo hook falliscono, può uscire con stato diverso da zero e impedire il commit della patch.
  • post-applypatch: Git lo esegue dopo aver applicato la patch e creato il commit. Non può annullare il commit, ma è utile per logging o invio di notifiche.
  • applypatch-msg: Git lo esegue prima che git am applichi la patch. Usalo per verificare o modificare il messaggio di commit proposto per la patch.

Hook lato server: categorie e casi d’uso

Gli hook lato server vengono eseguiti sui server Git remoti e si attivano quando si verificano eventi remoti, ad esempio prima o dopo un push su un repository.

  • pre-receive: Il remoto lo esegue prima di accettare un push. Puoi usarlo per far rispettare uno stile di codice coerente tra gli utenti o eseguire controlli di sicurezza prima di accettare le modifiche da un client.
  • update: Mentre pre-receive viene eseguito una volta per push, l’hook update viene eseguito per ogni riferimento (branch o tag) che viene modificato in un singolo push.
  • post-receive: Viene eseguito dopo il completamento del push. È spesso usato per inviare notifiche, fare logging approfondito o avviare pipeline CI/CD.
  • post-update: Viene eseguito dopo che Git aggiorna tutti i riferimenti in un push. Puoi usarlo per notifiche semplici perché, a differenza di post-receive, non può accedere sia ai log vecchi che a quelli nuovi di ogni aggiornamento dei riferimenti.
  • reference-transaction: Si attiva quando una transazione di riferimenti viene preparata, confermata o annullata, quindi può essere eseguito più volte. Usalo per validare o rifiutare aggiornamenti su più riferimenti in un’unica transazione, o per registrare e auditare i cambiamenti.
  • push-to-checkout: Si attiva quando fai git push su un branch che è attualmente in checkout sul remoto. Con questo hook puoi aggiornare i file sul server dopo un push, registrare le modifiche o bloccare push non sicuri direttamente sulla working directory.
  • pre-auto-gc: Viene eseguito poco prima che Git avvii la garbage collection automatica. Puoi usarlo per registrare l’inizio della GC, bloccarla durante operazioni pesanti o gestire attività necessarie pre-GC.
  • proc-receive: Viene eseguito quando il comando git-receive-pack elabora un push in arrivo. Aggiorna i riferimenti (branch e tag) nel repository remoto e riporta i risultati al client.

Configurare i Git Hook

In questa sezione trovi i passaggi per installare e configurare i Git hook. Vedrai anche come creare hook personalizzati da zero. 

Meccaniche di installazione e configurazione

Quando inizializzi un repository Git, Git crea automaticamente un set di hook nella cartella .git/hooks. Per vederli, apri il terminale e vai alla root del repository dove hai eseguito git init. Da lì, apri la directory nascosta .git e poi la sottodirectory hooks. Un semplice comando cd fa tutto questo e ti porta nella sottodirectory degli hook.

cd .git/hooks

Una volta dentro, vedrai gli hook di default con l’estensione .sample. Per abilitare un hook di default, rimuovi l’estensione .sample per quell’hook e rendilo eseguibile.

Per esempio, usa il comando sotto per rimuovere l’estensione .sample dall’hook pre-commit.

mv .git/hooks/pre-commit.sample .git/hooks/pre-commit

Poi rendilo eseguibile con il comando seguente:

chmod +x .git/hooks/pre-commit

Questo copre la modifica e l’abilitazione degli hook di default. Per creare hook personalizzati da zero, segui questi passaggi.

Per aprire un nuovo file in .git/hooks/, esegui:

nano .git/hooks/commit-msg

Crea lo script in questo file. Esempio:

 #!/bin/sh
echo "✅ Commit message hook triggered"

Salva ed esci, poi rendilo eseguibile:

chmod +x .git/hooks/commit-msg 

Nell’esempio sopra, ogni volta che il commit va a buon fine, gli hook stampano il messaggio " Commit message hook triggered"

C’è un altro modo per configurare hook personalizzati. Quando inizializzi un repository, Git include gli hook di default. Puoi modificare questi default usando directory template. 

Ecco come funziona: quando esegui git init, Git copia il contenuto della directory template globale nella directory .git/ del nuovo repository, inclusi gli hook. Se aggiungi script personalizzati di hook alla directory template globale, ogni nuovo repository che crei erediterà automaticamente questi hook.

Creare e personalizzare gli script degli hook

Per prima cosa, devi capire cosa vuoi ottenere. Vuoi intercettare messaggi di commit vaghi, impedire push accidentali o svuotare cache? Definire l’obiettivo in anticipo è importante perché i diversi hook Git servono a scopi diversi e devi sapere quale usare. 

Per esempio, se vuoi controllare lo stile del messaggio di commit, userai l’hook commit-msg. Se vuoi evitare certi push sul branch main, dovresti farlo con un hook pre-push. 

Una volta scelto l’hook, la decisione successiva è il linguaggio. Su macOS e Linux, spesso basta un piccolo script Bash (o sh). Su Windows, alcuni team preferiscono PowerShell. 

Se il tuo repo è poliglotta, potresti preferire un interprete universale come Python o Node.js così tutti possono eseguire la stessa logica. Quindi, la chiave è includere uno shebang (#!/bin/sh, #!/usr/bin/env python3, ecc.) in cima in modo che Git sappia come eseguirlo.

Un semplice esempio di hook pre-commit che impedisce il commit di file .env. Questo evita di pushare accidentalmente chiavi API sensibili.

#!/bin/sh

# Block committing secrets
if git diff --cached --name-only | grep -q ".env"; then
  echo "❌ .env file detected in commit! Remove it before committing."
  exit 1
fi

exit 0

Quando vuoi disabilitare gli hook, il modo più semplice è rinominarli temporaneamente (cambia pre-commit in pre-commit.off) o rimuovere il permesso di esecuzione. 

Se però vuoi solo bypassarli una volta, usa git commit --no-verify per saltare gli hook di commit e git push --no-verify per saltare gli hook di push. Puoi anche disabilitarli globalmente indicando a Git una cartella vuota con git config core.hooksPath /dev/null.

Casi d’uso comuni dei Git Hook ed esempi

I Git hook sono particolarmente utili per automatizzare test, controlli di sicurezza e far rispettare standard di qualità nel tuo workflow. 

Scenari pratici di automazione

Far rispettare lo stile del codice o il linting: l’hook pre-commit è spesso usato per automatizzare la formattazione del codice e intercettare potenziali errori prima che il commit vada a buon fine.

Per esempio, nel seguente hook pre-commit, prettier si occupa automaticamente della formattazione e mette in stage le modifiche prima del commit. Subito dopo può essere eseguito un linter e il commit riesce solo se il linting passa. Se fallisce, il commit viene bloccato.

#!/bin/sh

# Collect staged JS/TS files
FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(js|ts|tsx)$')
[ -z "$FILES" ] && exit 0

echo "Formatting with Prettier..."
npx --yes prettier --write $FILES

# Re-stage files that Prettier changed
echo "$FILES" | xargs git add

echo "Linting with ESLint..."
npx --yes eslint $FILES
STATUS=$?

if [ $STATUS -ne 0 ]; then
  echo "ESLint found issues. Fix them or commit with --no-verify if needed."
  exit $STATUS
fi

echo "Pre-commit checks passed."
exit 0

Esegui test automatici: puoi impostare gli hook per eseguire test automatici prima di pushare modifiche. Per esempio, il seguente hook pre-push rileva e avvia automaticamente i pytest disponibili nel tuo repo prima del push.

#!/bin/sh
echo "Running tests before push..."
pytest -q
STATUS=$?
[ $STATUS -eq 0 ] || { echo "Tests failed. Push aborted."; exit $STATUS;

Blocca automaticamente il commit di dati sensibili: file sensibili come .env, .pem o .key spesso contengono segreti. Il seguente esempio di hook pre-commit cerca tali pattern e blocca il commit se li trova.

#!/bin/sh
set -e

STAGED=$(git diff --cached --name-only --diff-filter=ACM)

# Block dotenv and private keys
echo "$STAGED" | grep -E '\.env(\.|$)|(^|/)\.env$|\.pem$|\.key$|id_rsa$' >/dev/null 2>&1 && {
  echo "Sensitive file detected in staged changes. Remove it from the commit."
  exit 1
}

Consigli per scrivere Git Hook efficaci

Qui ho raccolto alcuni consigli che ho trovato utili quando scrivo Git hook. 

Mantieni gli hook veloci

Gli hook vengono eseguiti ogni volta che attivi determinate azioni Git, quindi mantienili leggeri. Se hai suite di test corpose, eseguili in CI invece che in hook locali per ottenere prestazioni migliori. Eseguire linters, formatter o controlli su tutto il repository a ogni commit ti rallenterà, quindi limita i controlli ai file effettivamente modificati.

Garantisci la compatibilità multipiattaforma 

Assicurati che i tuoi hook funzionino senza problemi su sistemi operativi diversi. Usa shebang portabili, gestisci in modo coerente le terminazioni di riga (usa LF al posto di CRLF) e non hardcodare percorsi assoluti. 

Affidati invece a PATH e a script locali di progetto come npm run lint o python -m in modo che girino su più ambienti.

Strategie di debug

Aggiungi logging verboso o un flag di debug (per esempio, HOOK_DEBUG=1) per tracciare come viene eseguito lo script. Stampa dettagli come la directory corrente, il branch o i file in stage. Questo rende più facile seguire il flusso di esecuzione e individuare dove le cose non vanno.

Prova gli hook con input diversi e simula scenari di fallimento in locale prima di pushare le modifiche. Se un hook blocca inaspettatamente l’avanzamento, puoi bypassarlo temporaneamente con il flag --no-verify di Git o usando variabili d’ambiente pensate per saltare gli hook.

Per mantenere un comportamento coerente tra sistemi operativi, evita comandi specifici dell’OS e preferisci linguaggi di scripting portabili.

Documenta chiaramente gli hook

Una buona documentazione migliora la comprensione nel team e facilita l’onboarding dei nuovi membri. Mantieni un README centrale che spieghi scopo, comportamento e utilizzo di ciascun hook. Includi come eseguirli, prerequisiti, troubleshooting e consigli per bypassarli. Fornisci anche le istruzioni di installazione/setup. 

Tecniche di implementazione avanzate e best practice per i Git Hook

Se sei un utente più avanzato, questi consigli possono aiutarti:

Ottimizzazione delle prestazioni

Per ottimizzare le prestazioni in workflow complessi, riduci le dipendenze esterne evitando librerie pesanti. Questo diminuisce i tempi di avvio e i possibili punti di fallimento. 

Metti in cache i risultati di processi costosi come il linting così da riutilizzarli quando i file non sono cambiati. 

Se gli hook includono più controlli, parallelizzali così da eseguirli in contemporanea. Inoltre, modularizza gli script degli hook. Significa strutturare gli hook come componenti riutilizzabili e piccoli che eseguono solo le parti rilevanti in base al contesto.

Chaining e orchestrazione degli hook

Usa il chaining degli hook per eseguire più azioni in un singolo evento Git. Per esempio, in un pre-commit potresti voler eseguire il linting, poi i test e poi la formattazione del codice, tutto in catena. Ogni comando viene eseguito in sequenza e, se uno fallisce (stato di uscita non zero), i successivi possono essere saltati per evitare un commit non valido. 

Quando le azioni dell’hook sono indipendenti, puoi anche eseguirle in parallelo per risparmiare tempo. È qui che usi l’orchestrazione per gestire l’esecuzione dei task nell’ordine corretto.

Gestione della configurazione 

Ogni repo ha la propria directory .git/hooks. Ciò significa che se vuoi gli stessi controlli (ad esempio, il linting) in più progetti, devi copiarli e incollarli ovunque. Un modo migliore è gestire gli hook in modo centralizzato così che tutti i repository possano accedervi ed eseguirli.

Puoi farlo con un unico comando: git config --global core.hooksPath ~/.githooks. Questo dice a Git di cercare gli hook nella cartella ~/.githooks. Qualsiasi hook tu crei lì viene condiviso automaticamente con tutti i tuoi repository.

Puoi anche rendere la logica degli hook più dinamica con file di configurazione (JSON o YAML). Invece di hardcodare logiche diverse per ogni repository, il tuo script di hook può leggere il file di configurazione del repository e applicare automaticamente le regole corrette.

Esecuzione condizionale

Dentro gli script degli hook puoi aggiungere condizioni semplici così da eseguirli solo quando rilevante. Può significare controllare il nome del branch attuale, vedere quali file sono davvero cambiati o leggere una variabile d’ambiente che indica di saltare l’esecuzione.

Se vuoi più controllo, usa un framework come pre-commit, dove dichiari in un file di configurazione quali hook eseguire in quale fase. Puoi anche aggiungere logica condizionale, come eseguire hook solo su certi branch, saltarli con variabili o persino aggiungere condizioni basate sul tempo. Questo rende gli script dinamici e aderenti ai workflow reali.

Strategie di collaborazione e condivisione 

Ci sono due modi per centralizzare i Git hook e condividerli tra repository e team:

Template Git

Quando inizializzi un repository, Git aggiunge alcuni hook predefiniti sotto la directory git/hooks. Questi provengono dal template predefinito di Git.

Per creare hook personalizzati in centrale, puoi creare una directory template di Git, scrivere lì i tuoi hook e impostare globalmente Git per usare questa nuova directory come template predefinito. 

git config --global init.templateDir /path/to/hooks-template

Ma questo metodo non prevede il versionamento degli hook. È particolarmente utile se i tuoi hook cambiano raramente. Se aggiorni spesso gli hook e hai bisogno del controllo di versione, ti conviene usare il metodo successivo.

Repository Git centrale

Crea un repository centrale dedicato, versionato, e conserva lì tutti i tuoi script di hook personalizzati, separato dai repo di progetto. In questo modo puoi aggiornare gli hook in modo indipendente dal codice del progetto. 

Questi hook dovrebbero essere standardizzati, cioè evita di hardcodare percorsi o valori legati a un singolo repository.

Questa configurazione è particolarmente utile per i team, dato che tutti possono ricevere regolarmente gli aggiornamenti e sincronizzarli nei propri progetti. 

Un approccio più efficiente è usare uno script di setup che clona il repo centrale degli hook e copia gli script nella directory .git/hooks di ciascun progetto. Esempio di script di setup: 

#!/usr/bin/env bash
set -euo pipefail

# Location of the shared hooks template repo
HOOKS_TEMPLATE_REPO="[email protected]:your-org/git-hooks-template.git"
HOOKS_TEMPLATE_DIR="$HOME/.git-hooks-template"

# Clone or update the template repo
 echo "Cloning hooks template repo..."
 git clone "$HOOKS_TEMPLATE_REPO" "$HOOKS_TEMPLATE_DIR"

# The repo where you want hooks installed
TARGET_REPO="${1:-$(pwd)}"
TARGET_HOOKS_DIR="$TARGET_REPO/.git/hooks"

# --- Copy strategy ---
echo "Copying hooks into $TARGET_HOOKS_DIR..."
cp -r "$HOOKS_TEMPLATE_DIR/"* "$TARGET_HOOKS_DIR/"

# 4. Make sure hooks are executable
chmod +x "$TARGET_HOOKS_DIR"/* || true

echo "✅ Hooks installed successfully into $TARGET_REPO"

Un’altra opzione è usare symlink. Puoi collegare la directory .git/hooks di ogni progetto agli script nel tuo repo di hook versionato. Così, quando aggiorni il repo centrale, gli hook si aggiornano automaticamente perché il symlink punta lì.

Per mantenere affidabile questo sistema, definisci un processo chiaro per la manutenzione degli hook. I membri del team dovrebbero proporre modifiche agli hook con pull request, fare merge solo dopo la revisione e tenere la documentazione aggiornata man mano che gli hook evolvono. 

Integrazione dei Git Hook nei workflow di sviluppo

I Git hook giocano un ruolo importante nella continuous integration (CI). In breve, CI significa integrare spesso le modifiche, poi eseguire build e test per intercettare in anticipo i problemi. Collegando gli hook con strumenti CI/CD come Jenkins, GitHub Actions o GitLab CI, puoi avviare build, eseguire test e persino distribuire applicazioni automaticamente in base agli eventi Git.

Per esempio, un hook lato server pre-receive esegue uno script personalizzato sul server Git prima di accettare un push. Se lo script fallisce, il server rifiuta il push. Puoi usarlo per verificare se l’ultima build CI su quel branch è passata prima di consentire il push. Quel run CI potrebbe includere controlli di copertura del codice, test unitari o di integrazione o persino scansioni di sicurezza.

Gli hook possono anche automatizzare le attività di deployment. Un post-receive può attivare un webhook che avvia una pipeline CI/CD. Quando il codice viene unito su main, avvia automaticamente il ciclo build → deploy → release.

Considerazioni sulla sicurezza e best practice 

Se mantieni hook centrali per facilitare la collaborazione e avere un’unica fonte di verità, assicurati che la directory degli hook abbia permessi di file sicuri per prevenire accessi non autorizzati. Solo utenti fidati dovrebbero avere permessi di scrittura. 

Devi sempre validare gli input o i parametri ricevuti dagli script degli hook per evitare attacchi di code injection. Per esempio, valida gli input con pattern rigorosi come consentire solo nomi di branch alfanumerici e con trattini, o tag che corrispondono a vMAJOR.MINOR.PATCH. 

Non hardcodare mai dati sensibili negli script degli hook. Usa invece variabili d’ambiente o strumenti dedicati di secret management per fornire le credenziali in modo sicuro a runtime. Puoi integrare strumenti come Gitleaks con i pre-commit per eseguire scansioni di sicurezza alla ricerca di informazioni sensibili nelle modifiche che stai per commitare.

Qualcuno potrebbe reindirizzare il tuo hook per inviare codice o informazioni a un server diverso. Quindi limita i domini raggiungibili dai tuoi hook. Usa un proxy o un firewall per bloccare server di destinazione sconosciuti. Assicurati anche che i log non mostrino informazioni riservate nei messaggi a schermo. 

Conclusione

I Git hook sono un modo potente per automatizzare attività e far rispettare standard direttamente nel tuo workflow di sviluppo. Aiutano in tutto: dallo stile del codice e i test fino al deployment e ai controlli di sicurezza.

Usandoli bene, riduci gli errori, risparmi tempo e rendi la collaborazione tra team più fluida.

Inizia con semplici controlli pre-commit, poi sperimenta configurazioni più avanzate come orchestrazione, gestione centralizzata o integrazioni CI/CD. Se usi Git e vuoi migliorare le tue competenze, dai un’occhiata a questo corso avanzato su Git.

FAQ sui Git Hook

Dove trovo i Git hook?

Il percorso predefinito di Git per gli hook è . git/hooks e questa cartella è solitamente nascosta, quindi puoi accedervi solo da bash o dal terminale.

Quali sono le best practice per impostare i pre-commit hook?

Mantieni gli hook veloci ed eseguili sui file in stage per prestazioni migliori. Non usare i pre-commit per attività che richiedono molto tempo, come eseguire un’intera suite di test: per quelle usa la tua pipeline CI/CD. E documentane chiaramente lo scopo. 

In cosa differiscono i Git hook lato server da quelli lato client?

Gli hook lato client vengono eseguiti sulle macchine degli sviluppatori per fornire feedback e correzioni automatiche. Esempi: pre-commit, pre-push.

Gli hook lato server vengono eseguiti sul server Git remoto ed effettuano controlli critici per pipeline di produzione fluide e un’efficace collaborazione di team. Esempi: pre-receive, update. Se un hook lato server rifiuta un push, quel push non va a buon fine.

Posso usare i Git hook per far rispettare gli standard di codice?

Usa pre-commit per formattare e fare linting, commit-msg per far rispettare le convenzioni sui messaggi, pre-push per test veloci e pre-receive lato server per bloccare i segreti prima che finiscano sul remoto.

Srujana Maddula

Autore

Srujana Maddula

Srujana è una tech writer freelance con una laurea quadriennale in Informatica. Scrivere di vari argomenti, tra cui data science, cloud computing, sviluppo, programmazione, sicurezza e molti altri, le viene naturale. Ama la letteratura classica ed esplorare nuove destinazioni.

Argomenti

Correlato