Ricerca…
Sintassi
- .git / ganci / applypatch-msg
- .git / ganci / commit-msg
- .git / ganci / post-aggiornamento
- .git / ganci / pre-applypatch
- .git / ganci / pre-commit
- .git / ganci / preparare-commit-msg
- .git / ganci / pre-push
- .git / ganci / pre-rebase
- .git / ganci / aggiornamento
Osservazioni
--no-verify
o -n
per saltare tutti gli hook locali sul comando git dato.
Ad esempio: git commit -n
Le informazioni su questa pagina sono state raccolte dai documenti ufficiali di Git e da Atlassian .
Commit-msg
Questo hook è simile al hook prepare-commit-msg
, ma viene chiamato dopo che l'utente ha inserito un messaggio di commit piuttosto che prima. Questo di solito viene usato per avvisare gli sviluppatori se il loro messaggio di commit è in un formato errato.
L'unico argomento passato a questo hook è il nome del file che contiene il messaggio. Se non ti piace il messaggio che l'utente ha inserito, puoi modificare questo file sul posto (come prepare-commit-msg
) o puoi interrompere completamente il commit uscendo con uno stato diverso da zero.
L'esempio seguente viene utilizzato per verificare se il ticket di parole seguito da un numero è presente sul messaggio di commit
word="ticket [0-9]"
isPresent=$(grep -Eoh "$word" $1)
if [[ -z $isPresent ]]
then echo "Commit message KO, $word is missing"; exit 1;
else echo "Commit message OK"; exit 0;
fi
Ganci locali
I hook locali riguardano solo i repository locali in cui risiedono. Ogni sviluppatore può modificare i propri hook locali, quindi non possono essere utilizzati in modo affidabile come metodo per imporre una politica di commit. Sono progettati per rendere più facile per gli sviluppatori aderire a determinate linee guida ed evitare potenziali problemi lungo la strada.
Esistono sei tipi di hook locali: pre-commit, prepare-commit-msg, commit-msg, post-commit, post-checkout e pre-rebase.
I primi quattro hook si riferiscono ai commit e consentono di avere un certo controllo su ciascuna parte nel ciclo di vita di un commit. Gli ultimi due consentono di eseguire alcune azioni extra o controlli di sicurezza per i comandi git checkout e git rebase.
Tutti i ganci "pre" consentono di modificare l'azione che sta per avvenire, mentre i ganci "post-" vengono utilizzati principalmente per le notifiche.
Post-checkout
Questo hook funziona in modo simile all'hook post-commit
, ma viene chiamato ogni volta che si verifica con successo un riferimento con git checkout
. Questo potrebbe essere uno strumento utile per eliminare la directory di lavoro dei file generati automaticamente che altrimenti causerebbe confusione.
Questo hook accetta tre parametri:
- la ref del precedente HEAD,
- il ref del nuovo HEAD, e
- una bandiera che indica se si trattava di un checkout del ramo o di un checkout del file (
1
o0
, rispettivamente).
Il suo stato di uscita non ha alcun effetto sul comando git checkout
.
Post-commit
Questo hook viene chiamato immediatamente dopo l'hook di commit-msg
. Non può modificare il risultato dell'operazione di git commit
, quindi è usato principalmente per scopi di notifica.
Lo script non accetta parametri e il suo stato di uscita non influisce in alcun modo sul commit.
Post-ricezione
Questo hook viene chiamato dopo un'operazione push di successo. In genere viene utilizzato per scopi di notifica.
Lo script non accetta parametri, ma invia le stesse informazioni di pre-receive
tramite input standard:
<old-value> <new-value> <ref-name>
Pre-commit
Questo hook viene eseguito ogni volta che si esegue git commit
, per verificare cosa sta per essere eseguito. È possibile utilizzare questo hook per ispezionare lo snapshot che sta per essere eseguito.
Questo tipo di hook è utile per eseguire test automatici per assicurarsi che il commit in entrata non rotti la funzionalità esistente del progetto. Questo tipo di hook può anche verificare gli spazi vuoti o gli errori EOL.
Nessun argomento viene passato allo script di pre-commit e l'uscita con uno stato diverso da zero interrompe l'intero commit.
Prepare-commit-msg
Questo hook viene chiamato dopo l'hook pre-commit
per popolare l'editor di testo con un messaggio di commit. In genere viene utilizzato per modificare i messaggi di commit generati automaticamente per i commit compressi o uniti.
Da uno a tre argomenti vengono passati a questo hook:
- Il nome di un file temporaneo che contiene il messaggio.
- Anche il tipo di commit
- messaggio (opzione
-m
o-F
), - modello (opzione
-t
), - unire (se si tratta di un merge commit), o
- schiacciare (se è schiacciare altri commit).
- messaggio (opzione
- L'hash SHA1 del commit pertinente. Viene dato solo se è stata data l'opzione
-c
,-C
o--amend
.
Simile al pre-commit
, l'uscita con uno stato diverso da zero interrompe il commit.
Pre-rebase
Questo hook viene chiamato prima che git rebase
inizi a modificare la struttura del codice. Questo hook viene in genere utilizzato per assicurarsi che un'operazione di rebase sia appropriata.
Questo hook richiede 2 parametri:
- il ramo a monte dal quale la serie è stata biforcuta, e
- il ramo che viene ridefinito (vuoto quando si ridisegna il ramo corrente).
È possibile interrompere l'operazione di rebase uscendo con uno stato diverso da zero.
Pre-ricezione
Questo hook viene eseguito ogni volta che qualcuno utilizza git push
per inviare commit al repository. Risiede sempre nel repository remoto che è la destinazione del push e non nel repository di origine (locale).
L'hook viene eseguito prima che eventuali riferimenti vengano aggiornati. In genere viene utilizzato per applicare qualsiasi tipo di politica di sviluppo.
Lo script non accetta parametri, ma ogni ref che viene inviato viene passato allo script su una riga separata sullo standard input nel seguente formato:
<old-value> <new-value> <ref-name>
Aggiornare
Questo hook viene chiamato dopo la pre-receive
e funziona allo stesso modo. Viene chiamato prima che qualcosa sia effettivamente aggiornato, ma viene chiamato separatamente per ogni ref che è stato spinto piuttosto che tutti i ref in una volta.
Questo hook accetta i seguenti 3 argomenti:
- nome dell'aggiornamento in fase di aggiornamento,
- nome oggetto vecchio memorizzato nel riferimento e
- nuovo nome oggetto memorizzato nel rif.
Questa è la stessa informazione passata per la pre-receive
, ma poiché l' update
è invocato separatamente per ogni ref, puoi rifiutare alcuni refs mentre ne permetti altri.
Pre-push
Disponibile in Git 1.8.2 e versioni successive.
I ganci pre-push possono essere utilizzati per impedire che una spinta si sposti. I motivi per cui è utile sono: bloccare manualmente le spinte manuali accidentali a rami specifici, o bloccare i push se un controllo prestabilito fallisce (unit test, sintassi).
Un hook pre-push viene creato semplicemente creando un file chiamato pre-push
in .git/hooks/
, e ( gotcha alert ), assicurandosi che il file sia eseguibile: chmod +x ./git/hooks/pre-push
.
Ecco un esempio di Hannah Wolfe che blocca una spinta da padroneggiare:
#!/bin/bash
protected_branch='master'
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
if [ $protected_branch = $current_branch ]
then
read -p "You're about to push master, is that what you intended? [y|n] " -n 1 -r < /dev/tty
echo
if echo $REPLY | grep -E '^[Yy]$' > /dev/null
then
exit 0 # push will execute
fi
exit 1 # push will not execute
else
exit 0 # push will execute
fi
Ecco un esempio di Volkan Unsal che assicura che i test di RSpec passino prima di consentire il push:
#!/usr/bin/env ruby
require 'pty'
html_path = "rspec_results.html"
begin
PTY.spawn( "rspec spec --format h > rspec_results.html" ) do |stdin, stdout, pid|
begin
stdin.each { |line| print line }
rescue Errno::EIO
end
end
rescue PTY::ChildExited
puts "Child process exit!"
end
# find out if there were any errors
html = open(html_path).read
examples = html.match(/(\d+) examples/)[0].to_i rescue 0
errors = html.match(/(\d+) errors/)[0].to_i rescue 0
if errors == 0 then
errors = html.match(/(\d+) failure/)[0].to_i rescue 0
end
pending = html.match(/(\d+) pending/)[0].to_i rescue 0
if errors.zero?
puts "0 failed! #{examples} run, #{pending} pending"
# HTML Output when tests ran successfully:
# puts "View spec results at #{File.expand_path(html_path)}"
sleep 1
exit 0
else
puts "\aCOMMIT FAILED!!"
puts "View your rspec results at #{File.expand_path(html_path)}"
puts
puts "#{errors} failed! #{examples} run, #{pending} pending"
# Open HTML Ooutput when tests failed
# `open #{html_path}`
exit 1
end
Come puoi vedere, ci sono molte possibilità, ma il pezzo principale è di exit 0
se accadono cose buone, e di exit 1
se accadono cose brutte. Ogni volta che exit 1
la spinta verrà impedita e il tuo codice sarà nello stato in cui si trovava prima di eseguire git push...
Quando si utilizzano ganci lato client, tenere presente che gli utenti possono saltare tutti i ganci lato client utilizzando l'opzione "--no-verify" su una pressione. Se ti affidi al processo per far rispettare il processo, puoi essere bruciato.
Documentazione: https://git-scm.com/docs/githooks#_pre_push
Campione ufficiale: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample
Verifica la build di Maven (o altro sistema di build) prima di eseguire il commit
.git/hooks/pre-commit
#!/bin/sh
if [ -s pom.xml ]; then
echo "Running mvn verify"
mvn clean verify
if [ $? -ne 0 ]; then
echo "Maven build failed"
exit 1
fi
fi
Inoltrare automaticamente determinati push ad altri repository
post-receive
ganci post-receive
possono essere utilizzati per inoltrare automaticamente i push in arrivo a un altro repository.
$ cat .git/hooks/post-receive
#!/bin/bash
IFS=' '
while read local_ref local_sha remote_ref remote_sha
do
echo "$remote_ref" | egrep '^refs\/heads\/[A-Z]+-[0-9]+$' >/dev/null && {
ref=`echo $remote_ref | sed -e 's/^refs\/heads\///'`
echo Forwarding feature branch to other repository: $ref
git push -q --force other_repos $ref
}
done
In questo esempio, la regexp di egrep
cerca un formato di diramazione specifico (qui: JIRA-12345 usato per denominare i problemi di Jira). Puoi lasciare questa parte se vuoi inoltrare tutti i rami, ovviamente.