Git Hooks Pré-commit, Pré-push e Intercepção de Códigos Defeituosos na Porta
Os hooks pré-commit, commit-msg e pré-push são scripts em shell que executam antes que o git grave um commit ou envie uma push. Aqui está como configurá-los para capturar falhas de lint, mensagens de commit ruins e segredos vazados — com exemplos reais que você pode usar hoje.
O Git inclui hooks — scripts em shell que são executados em pontos específicos do seu fluxo de trabalho. A maioria dos repositórios os possui, inativos, em .git/hooks/ como .sample arquivos. A maioria dos desenvolvedores os ignora até que um commit defeituoso ou uma chave API vazada os faça desejar que não o tivessem feito.
Este conteúdo aborda os três hooks que vale a pena configurar em cada projeto: pre-commit, commit-msge, e pre-push. Cada um detecta um tipo diferente de erro. Cada um é um script em shell que você pode copiar e usar hoje.
Onde os hooks estão
Cada repositório git possui um .git/hooks/ diretório. Execute ls .git/hooks/ e você verá arquivos de exemplo. O Git ignora tudo com o .sample sufixo. Para ativar um hook, remova o sufixo e torne-o executável:
cp .git/hooks/pre-commit.sample .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
O contrato é simples: saia com código 0 e o git continua. Saia com código não nulo e o git é interrompido, exibindo o que você escreveu no stderr.
pre-commit: seu hook de maior valor
O pré-commit executa após você digitar git commit mas antes que o objeto do commit seja escrito. Ele não consegue ver a mensagem do commit — ainda não é escrita. O que ele pode faz é inspecionar os arquivos estagados e recusa se algo parecer errado.
O detalhe crítico: use git diff --cached --name-only para obter apenas os arquivos que você realmente estagou. Realizar uma análise de código em todo o projeto em cada commit é lento e revela problemas que você não introduziu.
Exemplo de verificador de código (ESLint)
#!/bin/sh
# Lint only staged JS files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')
if [ -z "$STAGED_FILES" ]; then
exit 0
fi
echo "Running ESLint on staged files..."
echo "$STAGED_FILES" | xargs ./node_modules/.bin/eslint
if [ $? -ne 0 ]; then
echo "ESLint failed. Fix errors before committing."
exit 1
fi
exit 0
O --diff-filter=ACM a flag pula arquivos excluídos — não há sentido em verificar algo que você acabou de remover.
Exemplo de escaneamento de segredos
Um escaneamento de padrões direto que detecta erros óbvios — chaves API hardcoded, senhas em arquivos de configuração enviadas acidentalmente:
#!/bin/sh
# Block commits with obvious secrets
PATTERNS="(AWS_SECRET|api_key\s*=|password\s*=|PRIVATE KEY)"
if git diff --cached | grep -qiP "$PATTERNS"; then
echo "Potential secret detected in staged changes. Aborting commit."
exit 1
fi
exit 0
Para projetos além de protótipos, combine isso com um escaner dedicado. detect-secrets da Yelp funciona bem como um hook pré-commit — mantém um arquivo de base para que strings marcadas anteriormente não bloqueiem cada commit. trufflehog é melhor para escaneamento de histórico após o fato ou execução em CI.
commit-msg: impõe formato da mensagem
Este hook recebe um argumento: o caminho para um arquivo temporário contendo sua mensagem de commit em rascunho. Leia-o, valide-o e saia com código 1 para rejeitar. O arquivo é gravável — você pode normalizar a mensagem em vez de rejeitá-la, embora isso surja inesperadamente pela primeira vez.
Impedindo Conventional Commits é a utilização mais comum. O retorno é logs automatizados, saída legível e pipelines de CI que podem analisar os tipos de commit para decidir o que lançar: git log Isso não detectará uma mensagem válida que ainda seja sem sentido, como
#!/bin/sh
COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# type(scope): description — scope is optional
PATTERN="^(feat|fix|chore|docs|style|refactor|test|perf|ci|build|revert)(\(.+\))?: .{1,72}"
if ! echo "$COMMIT_MSG" | grep -qP "$PATTERN"; then
echo ""
echo "Invalid commit message. Use Conventional Commits format:"
echo " type(scope): short description"
echo ""
echo "Valid types: feat, fix, chore, docs, style, refactor, test, perf, ci, build, revert"
echo "Example: feat(auth): add OAuth2 login flow"
echo ""
echo "Your message: $COMMIT_MSG"
exit 1
fi
exit 0
. Isso é um problema de cultura, não de ferramenta. fix: fix thingspre-push: a última porta antes do origin
O pré-push é executado após
ser invocado, mas antes que qualquer dado seja enviado ao remoto. Ele recebe o nome e a URL do remoto via stdin. É aqui que os testes devem estar — não um verificador de código (que executa no pré-commit), mas testes reais que validam o comportamento. git push Uma verdade dura: se seu conjunto de testes leva mais de 60 a 90 segundos, as pessoas usarão
#!/bin/sh
echo "Running tests before push..."
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Push aborted."
exit 1
fi
exit 0
. Execute apenas testes unitários rápidos aqui. Testes de integração e E2E devem estar em CI, onde o lento é aceitável. Um hook que é lento o suficiente para ser ignorado é pior do que nenhum hook. --no-verifyIgnorar hooks — e quando isso é apropriado
Ambas as flags existem por uma razão. Um hook defeituoso bloqueando uma correção de emergência é o tipo de coisa que faz uma equipe inteira se recusar ao conceito de hooks do git. Use
git commit --no-verify
git push --no-verify
quando tiver uma razão legítima: um hook falhando em arquivos não relacionados ou uma emergência onde a correção importa mais do que a barreira. --no-verify Se você estiver usando isso com frequência, os hooks precisam ser ajustados. Os culpados mais comuns: execução muito lenta, falha em arquivos que não foram alterados ou correspondência de padrões com falsos positivos que você nunca limpou.
Compartilhando hooks com sua equipe
é local para cada clonagem — é intencionalmente não commitado ao repositório. Duas abordagens para que os hooks fiquem firmes:
.git/hooks/ Opção 1: core.hooksPath
Armazene os hooks em um diretório commitado (por exemplo,
), então indique o git para ele: .githooks/Para automatizar isso para novas clonagens, adicione um
git config core.hooksPath .githooks
script em prepare — o npm o executa automaticamente em package.json Torne os scripts executáveis, commit-os e qualquer pessoa que clonar e executar npm install:
{
"scripts": {
"prepare": "git config core.hooksPath .githooks"
}
}
receberá os hooks configurados automaticamente. npm install Opção 2: Husky
Opção 2: Husky
Husky é a escolha padrão para projetos em JavaScript/Node. Ele lida com a core.hooksPath conexão para você e dá a cada hook um arquivo próprio em .husky/:
npx husky init
Em seguida, adicione hooks como scripts em shell simples:
echo "npm test" > .husky/pre-push
chmod +x .husky/pre-push
O Husky 9 (lançado no início de 2024) eliminou completamente a configuração em JSON em favor de scripts em shell brutos. Mais simples do que as versões v4/v8 para novas configurações, mas a migração do Husky 4 é uma mudança quebrante que o guia oficial subestima — o formato antigo .huskyrc não funciona mais em absoluto. Se você estiver atualizando um repositório existente, reserve tempo para isso.
Repositórios não em JavaScript são melhor servidos pela abordagem core.hooksPath . Não há razão para incluir uma dependência Node apenas para gerenciamento de hooks.
Revise sua diferença antes que o hook seja executado
git diff --cached mostra as alterações estagadas no terminal. Quando você está comparando duas versões de um arquivo de configuração ou verificando o que uma refatoração realmente mudou em múltiplas edições, uma diferença visual é mais rápida para escanear. IO Tools’ Text Diff permite que você cole duas versões e veja exatamente o que mudou — útil quando você deseja auditar o que está indo para um commit antes que os hooks sejam executados.
Os hooks do Git são uma das poucas ferramentas de automação que vivem totalmente dentro do seu fluxo de trabalho existente — sem conta de CI, sem serviço extra, sem custo. Um hook pré-commit que rejeita uma falha de lint é tão confiável quanto o script em shell que você escreveu. Isso é uma característica: você pode ler, depurar e modificar em um minuto. Configure os três hooks acima e você terá fechado a maior lacuna entre “funciona localmente” e “funciona na main”.
Instale nossas extensões
Adicione ferramentas de IO ao seu navegador favorito para acesso instantâneo e pesquisa mais rápida
恵 O placar chegou!
Placar é uma forma divertida de acompanhar seus jogos, todos os dados são armazenados em seu navegador. Mais recursos serão lançados em breve!
Ferramentas essenciais
Ver tudo Novas chegadas
Ver tudoAtualizar: Nosso ferramenta mais recente foi adicionado em 18 de junho de 2026
