1001Ferramentas
🪝Geradores

Gerador de Git pre-receive hook

Gera um script bash pre-receive para Git server-side com validações de branch, autor e tamanho de commit.


  

Hooks Git pre-receive: porteiros server-side para todo push

Git hooks são scripts executáveis que o Git roda automaticamente em eventos específicos no ciclo de vida de um repositório. Hooks locais ficam em .git/hooks/; hooks server-side ficam em hooks/ dentro de um repositório bare no servidor. Qualquer arquivo nesses diretórios cujo nome bata com um evento conhecido e que esteja marcado como executável (chmod +x) vira o handler daquele evento. Scripts podem ser em qualquer linguagem desde que comecem com o shebang correto: #!/bin/bash, #!/usr/bin/env python3, #!/usr/bin/env node — o Git apenas faz fork e executa.

O hook pre-receive é o ponto de enforcement mais poderoso de todo o protocolo Git. Ele roda uma vez por push, no servidor, antes de qualquer ref ser atualizada. Recebe uma linha por ref em stdin, no formato <old-sha> <new-sha> <ref-name>. Se o script sai com status não-zero, o push inteiro é rejeitado — todas as branches, todas as tags, de forma atômica. Não existe accept parcial.

Esqueleto do script

#!/bin/bash
# .git/hooks/pre-receive  (chmod +x)
while read oldrev newrev refname; do
  if [ "$refname" = "refs/heads/main" ]; then
    echo "Push direto em main não é permitido" >&2
    exit 1
  fi
  # Rejeita commits cuja mensagem não segue Conventional Commits
  for sha in $(git rev-list "$oldrev".."$newrev"); do
    msg=$(git log --format=%s -n 1 "$sha")
    if ! echo "$msg" | grep -Eq '^(feat|fix|docs|chore|refactor|test)(\(.+\))?: '; then
      echo "Commit $sha violou Conventional Commits: $msg" >&2
      exit 1
    fi
  done
done
exit 0

Políticas comuns impostas pelo pre-receive

  • Bloquear push direto em main, master ou release/* — forçar toda mudança a passar por pull request.
  • Validar mensagens de commit contra Conventional Commits, IDs de ticket no Jira ou regex customizada.
  • Rejeitar segredos com gitleaks detect --staged ou trufflehog antes que vazem para o histórico.
  • Limitar tamanho do commit / push para evitar dumps de 5 GB poluindo o servidor.
  • Exigir aprovação de code review via chamada de API à plataforma.
  • Exigir commits assinados usando git verify-commit em cada revisão.

A família completa de hooks

  • pre-commit — roda localmente antes do git commit criar o objeto de commit; perfeito para linters.
  • commit-msg — recebe o caminho do arquivo de mensagem; permite validar ou reescrever.
  • pre-push — roda localmente antes de transferir objetos para o remoto.
  • pre-receive — roda no servidor antes de qualquer atualização de ref; rejeita o push inteiro.
  • update — roda no servidor uma vez por ref; pode aceitar algumas refs e rejeitar outras.
  • post-receive — roda no servidor depois das refs serem atualizadas; ideal para triggers de CI e deploys.
  • post-merge, post-checkout, post-rewrite — hooks locais de notificação para plugins de IDE ou instaladores de dependências.

Suporte por plataforma e alternativas

Hooks server-side dependem totalmente da plataforma de hospedagem. Git puro (bare repo via SSH self-hosted) dá liberdade total. Gitea, Gogs e Forgejo expõem pre-receive pela UI admin. GitHub Enterprise Server suporta pre-receive hooks no nível da instância, mas o GitHub.com não — você precisa replicar as mesmas verificações via GitHub Actions, branch protection rules e required status checks. GitLab oferece push rules (Premium) e hooks server-side custom; Bitbucket Data Center tem seu próprio SDK. Sempre teste a matriz que você atende antes de depender de bash para enforcement.

Como hooks locais não são versionados com o repositório (tudo embaixo de .git/ é ignorado), eles não podem ser confiados como fronteira de segurança. Husky, lefthook, pre-commit e simple-git-hooks distribuem hooks via arquivos commitados no repo e religados via core.hooksPath, mas um contribuidor malicioso ainda pode burlar com git commit --no-verify. A única camada confiável de enforcement é o lado servidor — por isso o pre-receive importa.

FAQ

O GitHub.com aceita hooks pre-receive custom? Não. Use Actions com required status checks, branch protection rules e CODEOWNERS para enforcement de review.

Como instalar o hook? Copie o script para o diretório hooks/ do repositório bare e rode chmod +x pre-receive. O Git executa no próximo push.

Posso chamar programas externos do hook? Sim — bash, python, node, até binários compilados. Mantenha o startup barato; o hook roda em todo push e hooks lentos irritam dev.

Por que meu push trava para sempre? A saída do hook volta para o cliente pela rede. Se o script escreve em /dev/tty ou pede input, vai bloquear indefinidamente — sempre leia entrada apenas de stdin e escreva mensagens para o usuário em stderr.

Como furar o hook em emergência? Hooks server-side não podem ser burlados pelo cliente. Adicione um break-glass (ex: trailer [emergencia] que o hook reconhece) condicionado à membership do grupo, ou desabilite temporariamente o hook com acesso root no servidor.

Ferramentas Relacionadas