O Que São Git Hooks?
Git Hooks são scripts que o Git executa automaticamente em determinados momentos do seu ciclo de vida, como antes de um commit, após um push, ou antes de um merge. Eles funcionam como pontos de interrupção que permitem adicionar lógica personalizada ao seu fluxo de trabalho Git. Imagine poder executar testes automaticamente antes de cada commit, garantir que suas mensagens de commit sigam um padrão, ou até mesmo formatar seu código antes que ele seja salvo. Isso é o poder dos Git Hooks.
Existem dois tipos principais de Git Hooks: os client-side (lado do cliente), que rodam na sua máquina local e afetam seu fluxo de trabalho individual, e os server-side (lado do servidor), que rodam em um servidor Git remoto e afetam a colaboração em equipe. Neste artigo, focaremos nos hooks client-side, que são os mais acessíveis e úteis para otimizar o trabalho individual e de pequenas equipes.
Tipos de Git Hooks Client-Side e Seus Usos
Os Git Hooks client-side são armazenados no diretório .git/hooks/ do seu repositório. Quando você clona um repositório, o Git cria um template de hooks, mas eles não vêm habilitados por padrão. Para habilitar um hook, você precisa remover a extensão .sample do nome do arquivo e torná-lo executável.
Vamos explorar alguns dos hooks mais úteis:
pre-commit: Validação Antes do Commit
O hook pre-commit é executado antes que o Git solicite uma mensagem de commit. É o local ideal para realizar verificações rápidas no seu código:
- Formatação de Código: Use ferramentas como Prettier, Black (Python) ou ESLint para garantir a consistência do estilo do código. Se a formatação falhar, o commit é abortado.
- Linting: Execute linters para identificar erros de sintaxe, potenciais bugs e violações de regras de estilo.
- Testes Rápidos: Para projetos pequenos, você pode executar testes unitários rápidos para garantir que nenhuma alteração crítica quebre a funcionalidade básica.
- Verificação de Segredos: Evite commitar acidentalmente chaves de API, senhas ou outras informações sensíveis. Ferramentas como
git-secretspodem ajudar aqui.
Exemplo de uso: Imagine que você quer garantir que todo o código Python seja formatado com Black antes de commitar. Você criaria um arquivo .git/hooks/pre-commit com o seguinte conteúdo:
#!/bin/sh
if git rev-parse --verify HEAD >/dev/null 2>&1; then
against=HEAD
else
# Initial commit; we'll just let this use the index directly
against=$(git write-tree)
fi
# Check for modified Python files
if ! git diff-index --cached --name-only --diff-filter=d $against -- '*.py' | xargs -r black --check; then
echo "\nError: Black found code style issues. Please run 'black .' to format your code."
exit 1
fi
exit 0
Aviso de Segurança: Scripts em pre-commit rodam na sua máquina. Tenha cuidado com scripts de fontes não confiáveis, pois eles podem executar comandos maliciosos.
commit-msg: Padronizando Mensagens de Commit
Este hook é executado após você escrever a mensagem de commit, mas antes que o commit seja finalizado. Ele recebe o caminho para o arquivo contendo a mensagem de commit como argumento. É perfeito para garantir que suas mensagens sigam um padrão, como o Conventional Commits.
- Validação de Formato: Verifique se a mensagem começa com um tipo (feat, fix, chore, etc.), seguido por um escopo opcional e uma descrição.
- Requisito de JIRA/Ticket ID: Forçar a inclusão de um ID de ticket de um sistema de gerenciamento de projetos.
Exemplo de uso: Para garantir que toda mensagem de commit comece com um tipo válido (feat, fix, chore, refactor, docs, style, test, perf, build, ci, revert):
#!/bin/sh
message_file="$1"
# Regex to check for valid commit types at the beginning of the message
if ! grep -qE "^(feat|fix|chore|refactor|docs|style|test|perf|build|ci|revert)(\(.+\))?(!: |:) " "$message_file"; then
echo "\nError: Invalid commit message format."
echo "Please use a format like: 'feat: add new feature' or 'fix(auth): resolve login bug'"
exit 1
fi
exit 0
post-commit: Ações Pós-Commit
O hook post-commit é executado após um commit ser concluído com sucesso. Ele não pode abortar o commit, mas pode ser usado para:
- Notificações: Enviar notificações para ferramentas de chat (Slack, Discord) ou sistemas de monitoramento.
- Geração de Logs: Registrar informações sobre o commit em um arquivo de log local.
- Deploy Local Simples: Para fluxos de trabalho muito simples, pode disparar um deploy local ou um comando de atualização.
pre-push: Validação Antes do Push
Similar ao pre-commit, mas executado antes que um comando git push seja enviado para o repositório remoto. É o último ponto de verificação antes de compartilhar seu código:
- Execução de Testes Completos: Rode suítes de testes mais abrangentes que podem ser muito lentas para rodar em
pre-commit. - Verificação de Build: Garanta que o projeto compila corretamente.
- Análise Estática de Segurança (SAST): Execute ferramentas que analisam o código em busca de vulnerabilidades de segurança.
Exemplo de uso: Executar todos os testes unitários e de integração antes de permitir o push:
#!/bin/sh
# Assume que você tem um script 'run_all_tests.sh' que executa todos os seus testes
if ! ./run_all_tests.sh; then
echo "\nError: Tests failed. Please fix them before pushing."
exit 1
fi
exit 0
Configurando Git Hooks
Para configurar um hook, siga estes passos:
- Navegue até o diretório
.git/hooks/do seu repositório. - Crie um novo arquivo com o nome do hook desejado (ex:
pre-commit). - Adicione o script no topo do arquivo com a linha
#!/bin/shou#!/bin/bashpara indicar o interpretador. - Escreva a lógica do seu script.
- Torne o arquivo executável:
chmod +x .git/hooks/nome_do_hook.
Gerenciamento de Hooks em Equipe: Para garantir que todos na equipe usem os mesmos hooks, é uma boa prática versionar os scripts dos hooks em um diretório separado no seu repositório e usar um script de instalação para copiá-los e torná-los executáveis em .git/hooks/. Ferramentas como o Husky (para Node.js) ou pre-commit (framework Python) automatizam esse processo de gerenciamento e instalação, facilitando a adoção em projetos maiores ou em equipes.
Boas Práticas e Cuidados
- Comece Pequeno: Não tente automatizar tudo de uma vez. Comece com um ou dois hooks que tragam o maior benefício, como
pre-commitpara formatação. - Mantenha os Scripts Leves: Hooks que demoram muito para executar podem tornar o fluxo de trabalho lento e frustrante. Priorize verificações rápidas em
pre-commite tarefas mais longas empre-push. - Não Confie Apenas em Hooks: Hooks client-side podem ser desabilitados ou contornados pelo usuário (ex: usando
git commit --no-verify). Eles são uma camada de conveniência e qualidade, não uma garantia de segurança absoluta. Para políticas mais rigorosas, use hooks server-side ou ferramentas de CI/CD. - Versionamento dos Hooks: Se você não usar uma ferramenta de gerenciamento, considere adicionar seus scripts de hook a um diretório no seu projeto e criar um script de instalação que os copie para
.git/hooks/. Isso garante que todos na equipe usem as mesmas regras. - Evite Lógica Complexa: Para lógicas muito complexas, considere delegar para ferramentas de CI/CD. Hooks devem ser rápidos e focados.
Conclusão
Git Hooks são uma ferramenta poderosa e muitas vezes subutilizada para automatizar tarefas repetitivas, melhorar a qualidade do código e garantir a consistência do fluxo de trabalho. Ao implementar hooks como pre-commit e pre-push, você pode pegar erros comuns, formatar código automaticamente e ter mais confiança antes de enviar suas alterações. Para projetos pequenos, eles podem ser configurados manualmente, mas para equipes, ferramentas de gerenciamento de hooks simplificam a adoção e a manutenção. Comece a explorar os Git Hooks hoje mesmo e veja como eles podem transformar sua experiência de desenvolvimento.
Foto de Cemrecan Yurtman no Pexels.