FreeToGenerate.com

Todos os hooks, executados em vez de copiados do manual.

Consulte um hook

roda onde você trabalha

A documentação diz
não pode mudar o resultado, mas o status de saída dele vira o do comando
O que aconteceu de fato
a operação terminou e o comando falhou mesmo assim
Operação executada
git checkout
Código de saída
1

Maiúsculas não importam. Experimente post-checkout, pre-rebase ou reference-transaction — cada um desmente uma suposição diferente.

Medido, não copiado

hooks documentados
28
de fato executados
19
interromperam a operação
11
não mudaram nada
7
fizeram o comando falhar assim mesmo
1

Cada hook foi instalado sozinho, com um corpo que só falhava, num repositório descartável com um remoto bare local. Cada caso também rodou sem hook algum, e esse controle precisava dar certo antes de a medição valer.

O nome não é a regra. Só 6 dos 11 hooks que interromperam algo se chamam pre-alguma-coisa; applypatch-msg, commit-msg, prepare-commit-msg, update e reference-transaction também interrompem.

git version 2.54.0.windows.1

Os 28 hooks

28 à vista
HookOnde rodaDocumentadoMedido
applypatch-msgroda onde você trabalhasair com status diferente de zero aborta a operaçãoa operação foi interrompida
pre-applypatchroda onde você trabalhasair com status diferente de zero aborta a operaçãoa operação foi interrompida
post-applypatchroda onde você trabalhao status de saída é ignoradonão mudou absolutamente nada
pre-commitroda onde você trabalhasair com status diferente de zero aborta a operaçãoa operação foi interrompida
pre-merge-commitroda onde você trabalhasair com status diferente de zero aborta a operaçãoa operação foi interrompida
prepare-commit-msgroda onde você trabalhasair com status diferente de zero aborta a operaçãoa operação foi interrompida
commit-msgroda onde você trabalhasair com status diferente de zero aborta a operaçãoa operação foi interrompida
post-commitroda onde você trabalhao status de saída é ignoradonão mudou absolutamente nada
pre-rebaseroda onde você trabalhasair com status diferente de zero aborta a operaçãoa operação foi interrompida
post-checkoutroda onde você trabalhanão pode mudar o resultado, mas o status de saída dele vira o do comandoa operação terminou e o comando falhou mesmo assim
post-mergeroda onde você trabalhao status de saída é ignoradonão mudou absolutamente nada
pre-pushroda onde você trabalhasair com status diferente de zero aborta a operaçãoa operação foi interrompida
pre-receiveroda na ponta que recebe o pushsair com status diferente de zero aborta a operaçãoa operação foi interrompida
updateroda na ponta que recebe o pushsair com status diferente de zero aborta a operaçãoa operação foi interrompida
proc-receiveroda na ponta que recebe o pusho status de saída só conta em alguns estados
post-receiveroda na ponta que recebe o pusho status de saída é ignoradonão mudou absolutamente nada
post-updateroda na ponta que recebe o pusho status de saída é ignoradonão mudou absolutamente nada
reference-transactionroda onde você trabalhao status de saída só conta em alguns estadosa operação foi interrompida
push-to-checkoutroda na ponta que recebe o pushsair com status diferente de zero aborta a operação
pre-auto-gcroda onde você trabalhasair com status diferente de zero aborta a operação
post-rewriteroda onde você trabalhao status de saída é ignoradonão mudou absolutamente nada
sendemail-validateroda onde você trabalhasair com status diferente de zero aborta a operação
fsmonitor-watchmanroda onde você trabalhao status de saída só conta em alguns estados
p4-changelistroda dentro do git-p4sair com status diferente de zero aborta a operação
p4-prepare-changelistroda dentro do git-p4sair com status diferente de zero aborta a operação
p4-post-changelistroda dentro do git-p4o status de saída é ignorado
p4-pre-submitroda dentro do git-p4sair com status diferente de zero aborta a operação
post-index-changeroda onde você trabalhao status de saída é ignoradonão mudou absolutamente nada

A lista e a coluna documentada vêm do githooks(5), como ele acompanha o git. A coluna medida vem de executar cada hook.

Também disponível em: English · Español · Français · العربية

Git hooks: a lista completa e quais podem te barrar

O conjunto completo que o git documenta, e a resposta medida para a única questão que importa: este hook consegue interromper o que você está fazendo?

O que é um hook do git?

Um hook do git é um arquivo executável dentro do diretório de hooks do seu repositório, nomeado a partir de um momento da vida do git. Quando esse momento chega — você vai fazer um commit, acabou de mesclar, um push chegou ao servidor — o git executa o arquivo. É assim que um projeto impõe um formato de mensagem de commit, roda um linter antes de o código entrar ou recusa um push forçado à branch principal.

O git documenta 28 deles. A maioria das pessoas encontra três ou quatro. O resto cobre a aplicação de patches por e-mail, o rebase, a ponta que recebe um push, a coleta de lixo e uma ponte para o Perforce, e vários rodam em lugares que ninguém adivinharia pelo nome.

A pergunta com que qualquer um chega é simples: se este hook falhar, ele me barra? Toda referência que encontramos responde copiando a lista do manual do git. Esta página responde executando-os.

Como usar

  1. Digite o nome de um hook. Você recebe onde ele roda, o que a documentação do git diz sobre o status de saída dele e o que aconteceu quando ele foi de fato instalado e mandado falhar.
  2. Ou busque no conjunto inteiro. A tabela abaixo tem os 28. Buscar um comando do git — commit, push, git am — traz todos os hooks que disparam durante ele.
  3. Leia as duas colunas uma contra a outra. Elas vêm de lugares diferentes, então onde coincidem você pode confiar na resposta, e onde a documentação não tem palavra para o que acontece, a medição fornece uma.

O que aconteceu quando os executamos

Cada hook foi instalado sozinho, num repositório descartável com um remoto bare local ao lado, com um corpo que não fazia nada além de falhar. Depois a operação a que esse hook pertence foi realizada, e duas coisas foram registradas: o código de saída que o comando devolveu e se o estado do repositório de fato se moveu. Dezenove dos 28 podem ser acionados assim; os demais precisam de um depósito Perforce, um transporte de e-mail, o watchman ou o protocolo de push mais novo, e ficam em branco em vez de chutados.

Cada caso também rodou sem hook algum instalado, e esse controle precisava dar certo e mover o estado antes de a medição valer qualquer coisa. Não é cerimônia. A primeira versão deste experimento relatou que o hook pre-rebase não consegue interromper um rebase — o que é falso, e aconteceu porque a branch que ele montava não tinha nada a rebasear, então a operação não fazia nada havendo hook ou não. O controle transformou uma falsidade plausível e publicável numa falha barulhenta.

Dos dezenove: onze interromperam a operação, sete não mudaram absolutamente nada, e um fez algo para o qual não existe palavra comum.

O hook que falha sem falhar

O hook post-checkout não consegue interromper um checkout. A própria documentação do git diz que ele não pode afetar o resultado — exceto que o status de saída dele vira o status de saída do comando. Medido, é exatamente isso que acontece: o checkout se completa, você está na branch nova, e o git devolve 1.

Então um script escrito como um checkout seguido de um comando encadeado, que é como quase todo script de deploy e passo de CI é escrito, para seco num repositório cujo hook post-checkout falha. O checkout funcionou. O comando falhou. São fatos diferentes e só um deles é visível para o shell.

Vale conhecer mais um código de saída. Quando o hook reference-transaction recusa no estado prepared, o git não devolve uma falha comum — devolve 128, o código dele para erro fatal. Qualquer coisa que compare códigos de saída deveria esperar isso em vez de 1.

O nome não é a regra

Todo mundo aprende assim: hooks que começam com pre- podem barrar, hooks que começam com post- não. Metade está certa. Nada chamado post- interrompeu coisa alguma, e todo hook que não mudou absolutamente nada se chamava post-alguma-coisa.

A outra metade falha. Só 6 dos 11 hooks que interromperam uma operação se chamam pre-alguma-coisa. Os outros cinco são applypatch-msg, commit-msg, prepare-commit-msg, update e reference-transaction — ou seja, quase metade do que pode te barrar não avisa no nome. prepare-commit-msg é a armadilha dentro da armadilha: começa com as letras p-r-e, não é um hook pre-, e barra.

A regra de verdade é se o git consulta o status de saída no ponto em que o hook roda, o que é uma propriedade da operação e não do nome. É por isso que update interrompe um push, que reference-transaction pode impedir a criação de uma branch, e que post-checkout consegue fazer um comando falhar sem mudar nada.

O que esta página não consegue dizer

É uma versão do git numa plataforma. A medição foi tomada com a versão do git impressa ao lado dos números, no Windows, e embora a semântica dos hooks mude devagar, ela muda. Onde a documentação e a medição concordam — que é em tudo que se sobrepõe — a resposta é tão sólida quanto dá sem ler o código-fonte.

Nove hooks não foram medidos, e a linha deles diz isso em vez de ser preenchida. Um deles, pre-auto-gc, foi tentado e abandonado: a coleta automática de lixo só roda depois que o git decide que um repositório tem objetos soltos suficientes, e essa decisão amostra um diretório em vez de contar, então nenhum repositório de teste pequeno o bastante a disparava. Uma linha cujo controle não pode ser feito honesto fica de fora.

Por fim, isto trata de se um hook consegue interromper uma operação, não de se deveria. Um hook que recusa trabalho só serve se a pessoa barrada souber por quê, e o git não imprime nada em seu nome: o que o seu hook escrever na saída de erro é a mensagem inteira que qualquer um verá.

Por que é grátis?

A lista inteira são uns poucos kilobytes que viajam com a página e são pesquisados no seu navegador. Nada do que você digita é enviado, nada é registrado e não há conta a criar.

Sem cadastro, sem limites e sem marca d'água em nada que você copiar.