O Git pode parecer complexo, mas algumas de suas funcionalidades, como os Git hooks, exigem um entendimento mais aprofundado. Os Git hooks são scripts que o Git executa automaticamente em resposta a eventos específicos.

Embora possam ser simples, você tem muito mais espaço para usá-los de forma eficaz. No entanto, para fazer isso, você deve entender todas as engrenagens que compõem a roda inteira.

Neste artigo, veremos técnicas avançadas de Git hooks que incluem alguns fundamentos, como criá-los e instalá-los, e mais.

Ao longo do texto vamos explicar parâmetros dos hooks e variáveis de ambiente, oferecer algumas dicas e truques, analisar métodos de solução de problemas, e muitos outros tópicos.

Fundamentos dos Git hooks: uma introdução

Um dos principais recursos do Git são seus hooks — um mecanismo poderoso que permite automatizar tarefas, impor padrões e garantir fluxos de trabalho consistentes ao longo de todo o ciclo de vida de um projeto.

Os Git hooks são scripts executados automaticamente em pontos específicos do fluxo de trabalho do Git. Você pode usá-los para personalizar e estender o comportamento do Git para atender às necessidades do seu projeto. Os hooks garantem que a qualidade do código seja mantida, testes sejam executados e as implantações sejam orquestradas de forma suave.

O Git oferece vários tipos de hooks, e cada um deles é acionado em diferentes estágios do fluxo de trabalho do Git:

  • Pre-commit. Esses hooks são executados antes de finalizar um commit, permitindo que você imponha estilos de código, execute testes ou verifique erros de sintaxe.
  • Post-commit. É executado após a criação de um commit. É útil para notificações ou registros.
  • Pre-push. Este hook é acionado antes de você fazer push de código e permite realizar testes de integração, verificar a compatibilidade ou garantir a qualidade.
  • Post-push. O hook final é executado após a conclusão de um push. Como tal, é valioso para implantar código em produção ou atualizar a documentação.

Você encontrará hooks no diretório .git/hooks do seu repositório Git. Lá também há hooks de exemplo, que você pode usar como templates para criar seus próprios scripts personalizados. Os hooks abrangem uma série de ações e usam o sufixo sample- como referência:

Um diretório local do Git que mostra arquivos de hooks de exemplo.
Um diretório local do Git que mostra arquivos de hooks de exemplo.

Os hooks são acionados durante várias ações do Git. Por exemplo, um hook de pre-commit é executado quando você faz um commit de alterações, e um hook de pre-push é acionado antes de você fazer o push para o repositório remoto. Ao entender melhor esses gatilhos, você poderá implantar os hooks de forma mais estratégica para impor controle de qualidade e otimizar seu fluxo de trabalho.

Como criar e instalar Git hooks personalizados

Criar e instalar Git hooks básicos personalizados pode ser um processo complexo. Não obstante, os fundamentos que você usará aqui o prepararão para desenvolver hooks avançados posteriormente. Vamos repassar alguns conceitos que se aplicam a todos os hooks que você criar e instalar.

Escolhendo um tipo de hook adequado

Empregar o tipo de hook correto para o seu caso de uso específico é o importante primeiro passo. Você pode começar por compreender seu próprio fluxo de trabalho e necessidades de desenvolvimento. Esta é uma lista rápida de considerações para você verificar:

  • Primeiro, considere os vários estágios do seu processo, como codificação, testes e implantação. Então identifique onde esse processo poderia se beneficiar de automação e verificações.
  • A partir daí, localize pontos em seu fluxo de trabalho em que erros ou inconsistências ocorrem com frequência. Os Git hooks personalizados podem ajudar aqui. Por exemplo, se você se esquecer de executar testes antes de um commit, um hook de pre-commit pode resolver o problema.
  • Em seguida, considere quando você gostaria de executar o hook no seu fluxo de trabalho. Por exemplo, se quiser garantir que todos os commits atendam a padrões de codificação, um hook de pre-commit é apropriado. Se quiser validar o código antes de fazer o push para o repositório remoto, um hook de pre-push será mais adequado.
  • Por fim, certifique-se de que o tipo de hook que escolheu é compatível com seu ambiente de desenvolvimento e com as ferramentas que você usa. Considere a linguagem de script que você usará para o hook e seu ambiente de execução.

Neste ponto, você deve ser capaz de definir objetivos claros para o seu hook. Pode até ser que cada objetivo exija um tipo diferente de hook. Todavia, embora seja tentador criar scripts para todos os cenários possíveis, é uma boa ideia concentrar-se primeiro nos pontos mais dolorosamente críticos.

Nomeação e posicionamento de Git hooks personalizados

Nomear e posicionar corretamente Git hooks personalizados é crucial para garantir sua funcionalidade e manutenção. Assim como as funções, os arquivos, os nomes de classe e outros elementos do seu código, os Git hooks também devem ter uma convenção de nomenclatura consistente e descritiva.

Se os hooks forem dar suporte a vários projetos ao longo do tempo como templates, você pode querer usar prefixos — talvez com as iniciais do desenvolvedor, um departamento ou um nome de empresa. Em geral, os Git hooks usam letras minúsculas e hifens em prol da legibilidade — por exemplo, my-project-pre-commit.

Além disso, embora você possa armazenar os Git hooks no diretório .git/hooks do seu repositório, hooks personalizados ficam melhor em um diretório separado dentro da pasta raiz do projeto. Isso evitará substituições acidentais durante uma atualização do Git. Contudo, você deve implementar o controle de versão para esses hooks junto com o restante do código do seu projeto.

Como criar um Git hook básico personalizado

A maneira típica de escrever um Git hook básico é criar um novo arquivo com o nome do hook que você escolheu (por exemplo, pre-commit) no seu diretório de hooks. Listaremos os nomes dos hooks adiante, quando falarmos sobre parâmetros.

Antes de abrir um arquivo para trabalhar com ele, você deve garantir que ele seja executável usando o seguinte snippet de linha de comando:

chmod +x path/to/file/hook-name

Lembre-se de substituir nossos placeholders pelas informações corretas. Faremos referência a esse snippet ao longo do artigo, pois essa deve ser uma ação típica sempre que você criar um novo Git hook.

Quando o arquivo estiver executável e aberto, adicione sua lógica personalizada usando a linguagem de script que preferir: Bash, Python, Ruby e outras. A criação desses scripts, obviamente, está além do escopo do que abordaremos aqui. No entanto, há alguns exemplos de pseudocódigo mais adiante para demonstrar casos de uso e cenários específicos.

Por fim, antes de fazer o commit de qualquer alteração, teste seu hook tentando executar a ação relacionada (como um commit). Essa é a abordagem básica para criar Git hooks, mas há muitos casos de uso avançados. Veremos isso a seguir.

Como criar e instalar hooks personalizados avançados

A criação de Git hooks básicos é algo que você fará muito ao longo da sua carreira de desenvolvimento. Entretanto, muitas situações pedirão hooks mais avançados e complexos. A seguir veremos alguns casos de uso e exemplos de hooks para uma variedade de cenários comuns.

Crie um hook que imponha estilo de código usando linters

Usar um linter para impor estilo de código é uma aplicação fantástica dos Git hooks. Ele pode ajudar a manter a qualidade consistente do código em todo o seu repositório e deve ser algo de que você tirará muito proveito.

Obviamente, você deve escolher um linter que se adapte à linguagem de programação do seu projeto. Por exemplo, o Black é fantástico para Python. Aqui, usaremos o ESLint para JavaScript para criar um hook de pre-commit.

Primeiro, instale o linter como um pacote global ou local em seu projeto. Você precisará do Node.js e do npm para isso:

npm install eslint --save-dev

Em seguida, navegue até o diretório de hooks no seu repositório. Crie seu arquivo de pre-commit, e então escreva um script que execute o linter nos seus arquivos preparados. O hook deve impedir o commit se o linter encontrar qualquer problema. Aqui está um exemplo básico:

#!/bin/sh

# Stash unstaged changes (optional but recommended)
git stash -q --keep-index

# Run the linter on staged files
npm run lint # Replace with the appropriate linting command
LINT_RESULT=$?

# Unstash the stashed changes (optional but recommended)
git stash pop -q

# Exit with the linter's exit code
exit $LINT_RESULT

Quando tiver certeza de que o hook é executável, teste-o por meio de um commit. O hook de pre-commit deve executar o linter. Se houver alguma violação de estilo de código, você não poderá concluir o commit até corrigir os problemas.

Obviamente, você deve escrever um hook que funcione com seus próprios linguagem de programação e linter, de acordo com o seu projeto. Por exemplo, você poderia estender este exemplo com configurações de linter, integrando-o ao seu processo de build, e muito mais.

Implemente um hook para executar testes antes de um commit

Implementar um hook de pre-commit para executar testes antes de um commit é uma excelente maneira de detectar qualquer problema em potencial logo no início. Dessa forma você garante que o commit só passe código confiável.

Para este exemplo, usaremos o framework de testes Jest para JavaScript. Você deve instalar algo adequado ao seu projeto (como sempre):

npm install jest --save-dev

Como em todos os hooks, navegue até o diretório de hooks, crie um novo arquivo, dê um nome a ele e torne-o executável. A partir daqui, escreva um script que execute testes em todos os arquivos preparados antes do commit. Aqui está um modelo aproximado:

#!/bin/sh

# Stash unstaged changes (optional but recommended)
git stash -q --keep-index

# Run tests on staged files
npm test # Replace with the appropriate test command
TEST_RESULT=$?

# Unstash the stashed changes (optional but recommended)
git stash pop -q

# Exit with the test's exit code
exit $TEST_RESULT

Quando você tentar dar o commit das alterações, o hook executará os testes nos arquivos preparados. O commit será interrompido em caso de qualquer falha nos testes, e você deverá resolver os problemas antes de fazer o commit novamente.

Desenvolva um hook para automatizar o controle de versão e a marcação

Uma excelente maneira de simplificar o processo de lançamento é automatizar o controle de versão e a marcação no Git. Isso garantirá um controle de versão consistente em toda a sua base de código.

Para começar, escolha um esquema de controle de versão adequado ao seu projeto. Isso está além do escopo do artigo, mas esquemas comuns incluem o Semantic Versioning (SemVer) ou um padrão de controle de versão personalizado.

Em seguida, decida exatamente o que o seu hook fará. Por exemplo, ele pode ler a versão atual, incrementá-la de acordo com um esquema escolhido e atualizar os arquivos necessários com a nova versão. Você também desejará escrever um script para criar tags baseadas na versão, que usa comandos do Git para criar tags leves ou anotadas.

Após criar e definir as permissões para o seu arquivo, você pode começar a escrever o seu hook. Este pode ser um hook complexo e altamente específico que pode inclusive mudar de projeto para projeto. Entretanto, a maioria dos hooks desse tipo incluirá o seguinte:

  • Uma função que incrementa uma parte específica de uma string de versão (por exemplo, 1.2.3) e retorna a nova versão.
  • A capacidade de ler a versão atual de um arquivo de versão dedicado.
  • Uma função para calcular o novo número de versão, incluindo qual parte específica incrementar. Por exemplo, 0 para major, 1 para minor, 2 para patch.

A partir daí, o script deve atualizar o arquivo de versão com o novo número, criar uma tag leve com a nova versão e, opcionalmente, fazer o push da nova tag para um repositório remoto. Quando você fizer o commit das alterações, o hook garantirá que cada commit seja associado a uma versão e uma tag apropriadas.

É provável que você queira adequar ainda mais esse hook aos requisitos do seu projeto. Por exemplo, você poderia lidar com casos como criar tags iniciais, manejar conflitos de versão e atualizar referências de versão em arquivos.

Entendendo parâmetros de hook e variáveis de ambiente

Um dos motivos pelos quais os Git hooks são tão poderosos é a forma como lidam com variáveis dinâmicas. No entanto, esse conceito pode ser complexo de entender. A seguir, examinaremos variáveis de ambiente e parâmetros de hook, começando por este.

Como parâmetros passam para os hooks

Os hooks podem receber parâmetros específicos do Git para acessar informações contextuais da sua base de código principal. O Git define parâmetros automaticamente no momento da execução, e embora você não precise defini-los especificamente na maioria das vezes, pode ser necessário declará-los. É essencial entender esses parâmetros para desenvolver hooks eficazes.

Aqui, uma visão geral dos principais pontos a respeito de parâmetros de hook:

  • Git hooks usam variáveis posicionais, em que $1 se refere ao primeiro parâmetro, $2 ao segundo parâmetro, e assim por diante. Esses parâmetros não são arbitrários; eles têm significados e propósitos específicos. Assim, embora não sejam “oficiais”, eles representam convenções aceitas ao acessar os valores dos parâmetros.
  • A ordem dos parâmetros segue um padrão específico. O Git passa esses parâmetros para o seu script de hook em uma ordem predeterminada com base no contexto do evento do hook.
  • Os nomes das variáveis refletem a objetivo geral dos parâmetros. Por exemplo, $1 geralmente contém o caminho para um arquivo, enquanto $2 pode ser a fonte de uma ação.

Se você adicionar um parâmetro que o hook não possa chamar, geralmente o script não poderá utilizá-lo. Os parâmetros são específicos para um hook particular e para o contexto de execução. Para evitar problemas, você deve usar apenas parâmetros documentados. Contudo, você pode atribuir o valor de um parâmetro posicional a outra variável e depois usá-lo em seu script:

#!/bin/sh

# Assign $1 to the variable EXAMPLE
EXAMPLE=$1

# Use EXAMPLE variable
echo "The commit message file is: $EXAMPLE"

Neste caso, a variável EXAMPLE terá o mesmo valor que $1, que é o caminho para o arquivo de mensagem de commit. Porém, o uso dos nomes documentados de variáveis torna seu código mais compreensível.

Observe que, em alguns casos, você usará a entrada padrão (stdin) para definir parâmetros e, nesse caso, deverá incorporar esses elementos aos seus hooks.

Como encontrar valores e definições de parâmetros dos Git hooks

Visto que cada Git hook terá seus próprios parâmetros, você provavelmente precisará de uma referência para determinar quais são eles ao seu aplicativo específico. A boa notícia é que existem algumas maneiras de fazer isso.

Por exemplo, a documentação oficial dos Git hooks inclui alguns dos parâmetros mais comuns. Entretanto, a melhor abordagem é abrir um dos Git hooks de exemplo. Eles consistem em um miniguia sobre como criar o script do hook e incluirão definições de parâmetros pra você:

Um arquivo de Git hook de exemplo no NeoVim.
Um arquivo de Git hook de exemplo no NeoVim.

Eles são uma excelente maneira de se familiarizar com os Git hooks, e podem até mesmo ajudá-lo com parte do trabalho de codificá-los.

Variáveis de ambiente

Os Git hooks podem buscar argumentos a partir de argumentos da linha de comando e da entrada padrão stdin, conforme discutimos. No entanto, eles também podem buscar argumentos do próprio ambiente, já que são executados dentro de um shell bash.

Essas variáveis de ambiente permitem que você personalize o comportamento dos seus Git hooks e tome decisões baseadas em vários aspectos do fluxo de trabalho do Git. Dessa forma, você pode criar Git hooks dinâmicos e sensíveis ao contexto. Por exemplo, você pode usá-los para validar mensagens de commit, controlar o acesso a branches específicos ou disparar ações personalizadas com base na identidade do autor.

A listagem de todas as variáveis de ambiente também está além do escopo deste artigo. Recomendamos que você consulte a documentação do Git e hooks de exemplo para obter dicas sobre quais variáveis serão usadas.

Testando os valores das variáveis de ambiente

O Git normalmente define diferentes variáveis de ambiente automaticamente, dependendo do hook que ele chama. Como tal, isso pode causar problemas se você não estiver ciente do que está sendo definido. Por exemplo, considere o seguinte resultado para a variável GIT_REFLOG_ACTION nos hooks de pre-rebase e post-merge:

  • pre-rebase. GIT_REFLOG_ACTION=rebase
  • post-merge. GIT_REFLOG_ACTION=’pull other master’

Felizmente, há uma maneira de testar o que o Git fará com as variáveis de ambiente usando um pequeno snippet dentro do seu hook:

#!/bin/bash

echo Running $BASH_SOURCE
set | egrep GIT
echo PWD is $PWD

Para resumir o código, a linha dois imprime o script em execução no momento; a linha três define todas as variáveis de ambiente a serem exibidas e, em seguida, filtra-as para aquelas que contêm “GIT” no nome; a linha quatro imprime o diretório de trabalho atual.

Depois de executar isso, você verá a saída que corresponde às variáveis de ambiente associadas ao seu hook. A partir daqui, você terá o conhecimento necessário para garantir que seus próprios Git hooks possam utilizar variáveis de ambiente da maneira que desejar.

Dicas e truques para gerenciar e compartilhar seus Git hooks

Gerenciar Git hooks em uma equipe ou organização é crucial para garantir práticas de desenvolvimento consistentes e automatizar seus fluxos de trabalho de forma eficiente. Por exemplo, considere o simples ato de atribuir um diretório de hooks dedicado para hooks. Há dois conselhos que podemos dar aqui:

  • Crie um repositório central ou um local compartilhado onde você armazena hooks padronizados. Você pode reutilizar esses hooks em vários projetos e clonar ou vincular ao repositório para fornecer acesso global.
  • Organize seus hooks em uma estrutura de registros ou diretórios. Isso facilitará para a sua equipe encontrar e usar os hooks de que precisa.

Quanto maior a probabilidade de os hooks aparecerem em vários projetos, maior a importância da documentação. Você deve manter uma documentação abrangente que descreva a finalidade, formas de uso e opções de configuração de cada hook no repositório. Revisões de código e estratégias de atualização para esses hooks globais também são essenciais.

Recomendamos também que você armazene os hooks personalizados no Sistema de Controle de Versão (Version Control System, VCS) junto com a base de código do projeto. Isso garante que toda a equipe tenha acesso à biblioteca de hooks inteira.

Usando Git hooks do lado do servidor

Os hooks do lado do servidor serão executados no servidor que hospeda o repositório central do Git. Dessa forma, você pode aplicar políticas, realizar verificações ou disparar ações do lado do servidor.

Você tem duas opções de armazenamento para seus hooks do lado do servidor: dentro do VCS com o projeto, ou em repositórios separados.

Armazenamento de hooks do lado do servidor usando um VCS

Há duas vantagens em usar o VCS para armazenar hooks do lado do servidor. Primeiro, você pode assegurar que os hooks tenham o mesmo controle de versão e manutenção que o restante da sua base de código. Segundo, você só precisará clonar um repositório para acessar o código do projeto e os hooks.

Todavia, dependendo da natureza dos hooks específicos, armazená-los no mesmo repositório pode gerar preocupações de segurança se esses hooks acessarem informações confidenciais. Além disso, se os hooks forem complexos ou exigirem configurações específicas, isso poderá aumentar a complexidade do seu repositório principal.

Armazenamento de hooks do lado do servidor em repositórios separados

Manter hooks do lado do servidor em repositórios separados permite que você os atualize e controle sua versão de forma independente da sua base de código, o que pode reduzir possíveis conflitos. Essa modularidade pode oferecer maior flexibilidade.

Além disso, você pode armazenar esses hooks em repositórios com acesso restrito. Isso o ajudará a reduzir o risco de exposição de dados confidenciais.

Por outro lado, a manutenção de múltiplos repositórios pode exigir esforço adicional. Ademais, se os hooks dependerem de versões específicas da sua base de código principal, pode ser um desafio coordenar as alterações entre os repositórios.

Automatização de instalações de hooks

Automatizar as instalações de hooks em múltiplos repositórios pode economizar tempo e garantir a consistência do seu fluxo de trabalho de desenvolvimento. Usando scripts e templates, você pode configurar facilmente hooks em vários repositórios sem intervenção manual.

O processo começa com um repositório dedicado que contém seus hooks globais. Você desejará padronizá-los: por exemplo, evite codificar caminhos ou valores específicos de um único repositório.

A partir daí, você pode começar a escrever o seu script de instalação. Por exemplo, o pseudocódigo a seguir clonará um repositório de templates de hooks e copiará os hooks (ou fará um link simbólico deles) para o diretório .git/hooks de cada repositório:

# Example installation script
# Usage: ./install_hooks.sh /path/to/repository
TEMPLATE_REPO="https://github.com/yourusername/hooks-template.git"
REPO_PATH="$1"
REPO_NAME=$(basename "$REPO_PATH")

# Clone the template repository
git clone --depth 1 "$TEMPLATE_REPO" "$REPO_NAME-hooks"

# Copy or symlink hooks to the repository
cp -r "$REPO_NAME-hooks/hooks" "$REPO_PATH/.git/"
rm -rf "$REPO_NAME-hooks"
echo "Hooks installed in $REPO_NAME”

Após salvar as alterações, você pode executar o script de instalação para cada repositório em que deseja instalar os hooks:

./install_hooks.sh /path/to/repository1
./install_hooks.sh /path/to/repository2
# …

Faça alterações no repositório de templates sempre que precisar atualizar ou adicionar hooks. Da próxima vez que você executar o script de instalação em um repositório, os hooks atualizados serão instalados.

Templates do Git

Os templates do Git permitem definir hooks e configurações comuns para novos repositórios. Eles fornecem uma abordagem sistemática para ajudá-lo a automatizar definições, configurações e outros elementos quando você criar ou clonar novos repositórios. Dessa forma, você pode garantir que todos os repositórios sigam suas práticas típicas e estabelecidas.

Após criar um diretório de template e adicionar seus scripts de hook, você pode configurar o Git para usar o diretório como o template para novos repositórios. Você pode configurar isso em uma base global ou local para cada usuário.

Para configurações globais, aponte para o seu diretório de templates de hooks:

git config --global init.templateDir /path/to/hooks-template

Para configurações locais, você pode especificar o repositório exato:

git init --template=/path/to/hooks-template

Sempre que você criar um novo repositório usando git init ou clonar um repositório existente, o Git copiará automaticamente o conteúdo do seu diretório de templates de hooks para o diretório .git no novo repositório.

Por fim, embora hooks de template possam ser genéricos, você também pode permitir a personalização de hooks com base em necessidades específicas. Por exemplo, um script poderia verificar a existência de um arquivo de configuração de hook específico para um repositório e utilizá-lo se estiver presente.

Práticas típicas para ajudá-lo a manter os Git hooks seguros

O uso de Git hooks pode ser poderoso para automação de processos e aplicação de práticas típicas. No entanto, isso tem o potencial de introduzir vulnerabilidades se você não gerenciar seus hooks de maneira adequada.

Aqui está uma lista rápida de práticas que você pode implementar em seus próprios hooks:

  • Certifique-se de revisar e restringir as permissões dos hooks, especialmente se forem exemplos de terceiros.
  • Sempre valide e saneie seus parâmetros de entrada para mitigar injeções de código. Use práticas seguras, como evitar o uso direto de entradas de usuário em seus scripts.
  • Certifique-se de que os hooks não incluam informações confidenciais. É nesse ponto que variáveis de ambiente ou armazenamento seguro oferecem um valor imenso.
  • Revise e teste os hooks regularmente para evitar o consumo inintencional de recursos. Isso pode até resultar em ataques de Negação de Serviço Distribuído (Distributed Denial of Service – DDoS).

É desejável também implementar um processo completo e abrangente de teste e revisão. Isso ajudará a evitar vulnerabilidades e outros erros no futuro.

Validação

Precisamos falar um pouco mais sobre a implementação de validação adequada e tratamento de erros em seus hooks. Isso é fundamental para garantir confiabilidade, estabilidade e segurança.

Por exemplo, você deve sempre validar todas as entradas ou parâmetros que os scripts dos seus hooks recebem. Contudo, há muito mais que você pode fazer para garantir uma boa validação. Você pode garantir que o repositório esteja no estado esperado para que o hook seja executado com êxito. Por exemplo, em um hook de pre-commit, certifique-se de deixar os arquivos preparados necessários antes do commit.

Uma parte de um arquivo de Git hook mostrando o código exit 0 como linha final.
Uma parte de um arquivo de Git hook mostrando o código exit 0 como linha final.

O tratamento de erros também é valioso. Códigos de saída são tão importantes nos hooks quanto na base de código, assim como registros de erro e mensagens de erro informativas. A “falha graciosa” deve ser o seu objetivo aqui, assim como seria com bases de código maiores.

É claro que, em um cenário real, seus hooks podem precisar de uma lógica de validação e tratamento de erros mais complexa. Isso significa que os testes regulares são ainda mais importantes do que antes.

Ações destrutivas acidentais

Acidentes acontecem; então, configurar seus Git hooks para evitar ações destrutivas indesejadas é crucial para proteger contra perda ou danos dos dados. Os hooks podem essencialmente atuar como redes de segurança por meio de solicitações de confirmação do usuário para ações potencialmente prejudiciais.

Hooks de pre-receive e pre-commit funcionam bem aqui. Vamos examinar rapidamente como ambos podem ajudar você:

  • Hooks de pre-receive ajudam em verificações do lado do servidor. São acionados antes de aceitar novos branches ou tags do cliente. Seu script deve examinar as referências recebidas, verificar se há ações como force pushes ou exclusões de branches e solicitar confirmação do usuário. Você também desejará analisar as referências enviadas para determinar se envolvem ações como force pushing (--force) ou exclusão de branch.
  • Hooks de pre-commit funcionam no lado do cliente e são executados antes de você finalizar um commit. Embora não impeçam diretamente ações destrutivas no servidor, eles podem ajudar a evitar erros locais antes de fazer o push. Seu script deve analisar as alterações preparadas e procurar por elementos como comandos de force push nas mensagens de commit. A partir daí, exiba uma mensagem de aviso ou erro para o usuário.

No entanto, independentemente das práticas que você implementar, elas devem ser seguras, eficientes e adequadas às suas necessidades. Isso exigirá uma revisão completa e uma estratégia de testes.

Revisão e testes de Git hooks

Revisar e testar os hooks é essencial para garantir que funcionem corretamente e se alinhem com o seu fluxo de trabalho de desenvolvimento. Revisões por pares, documentação clara, uma abundância de comentários e outras ações podem ajudar a assegurar que os hooks estejam prontos para a produção.

Quando se trata de testes, é importante realizá-los de forma isolada, usando dados de amostra diversos. Você também pode implementar testes automatizados de regressão ou integração.

Por fim, recomendamos testar os hooks em diferentes ambientes (como os seus servidores de desenvolvimento, testes e produção) para garantir que apresentem um comportamento consistente. Uma configuração de registros em tempo real ajudará nesse caso, pois pode mostrar o que acontece quando os dados são movidos de servidor para servidor.

Como solucionar problemas com seus hooks

Assim como em qualquer base de código, você também pode ter de solucionar problemas em seus hooks — mesmo que isso exija algumas tentativas. Na verdade, não importa qual o tipo do seu Git hook, você descobrirá que os mesmos erros aparecem repetidamente. Muitos desses serão problemas simples que afetam todo tipo de projeto, como erros de sintaxe, problemas com permissões, uso de caminhos relativos ou codificados de forma rígida, e muito mais.

Todavia, também é uma boa ideia verificar se há dependências ausentes, pois alguns hooks dependem de ferramentas, arquivos ou bibliotecas externas. Assim, você precisa disponibilizá-los no ambiente em que executa o hook.

Porém, também podem surgir problemas específicos dos Git hooks. Por exemplo, os hooks devem sair com um código de status diferente de zero para indicar uma falha. Além disso, os hooks não devem conter loops infinitos. Sem essas duas precauções, você pode causar comportamentos inesperados e interromper seu fluxo de trabalho.

Você também pode descobrir que conflitos entre dois hooks resultam em interações e consequências indesejadas. As chamadas “condições de corrida” também podem frustrar suas expectativas. Isso ocorre quando dois ou mais hooks são acionados por eventos semelhantes, mas um deles é concluído antes do outro — com impacto no resultado esperado.

É nesse ponto que as revisões e os testes se tornam essenciais. Manter a documentação também é importante para evitar problemas e garantir que os hooks funcionem como você espera.

Falando em documentação, o próprio material de referência do Git é uma leitura essencial. Na verdade, juntamente com este artigo, e talvez o site do guia independente Git Hooks (usando o GitHub Pages), você não deverá sentir falta de material de leitura.

O site do guia Git Hooks.
O site do guia Git Hooks.

Entretanto, você também pode procurar aplicativos para ajudá-lo a gerenciar os Git hooks. O Lefthook tem atualizações regulares e bastante suporte no GitHub, enquanto o Husky é ótimo para fazer linting de suas mensagens de commit.

Os benefícios de integrar hooks em pipelines de integração contínua (CI/CD)

Os pipelines de CI/CD funcionam bem com os Git hooks, pois esses scripts podem ajudar você a automatizar tarefas, garantir qualidade consistente e fornecer verificações de segurança.

Por exemplo, hooks de pre-commit permitem que você execute verificações de qualidade de código, como linting, análise estática e formatação. Quando se trata de testes, você pode acionar testes unitários, suítes de testes ou outras verificações automatizadas no estágio de pre-commit. Por outro lado, hooks de pre-push permitem executar testes de integração, varredura de segurança, e outros.

Há muitos benefícios que você pode aproveitar com o uso de hooks em seus pipelines de CI/CD:

  • Consistência. Os hooks permitem que você imponha práticas consistentes em todos os commits e implantações, o que reduzirá erros em toda a linha.
  • Verificações automatizadas. Você pode automatizar verificações de qualidade de código, testes, varreduras de segurança e outras tarefas importantes. Isso reduzirá o trabalho manual e lhe proporcionará mais tempo para se dedicar a outras tarefas.
  • Detecção precoce de problemas. Os hooks permitirão que você detecte problemas no processo de desenvolvimento mais cedo, prevenindo que se propaguem pelo pipeline.
  • Redução de riscos de implantação. Com verificações e testes automatizados acionados por hooks, o risco de implantar código defeituoso pode ser significativamente reduzido.

Como a API da Kinsta permite configurar pipelines de CI/CD, também é possível integrar Git hooks aqui. A Kinsta possibilita baixar todo o seu repositório de um local remoto e permite pushes usando um plugin de terceiros, tal como o WP Pusher.

A página inicial do WP Pusher.
A página inicial do WP Pusher.

Naturalmente, isso também significa que você tem a opção de utilizar Git hooks. Dessa forma, sua instalação na Kinsta pode aproveitar-se desses poderosos scripts em seu repositório.

Resumo

O Git é uma ferramenta essencial para qualquer projeto de desenvolvimento, mas um aspecto dele em particular pode turbinar seu fluxo de trabalho de codificação e implantação. Os Git hooks permitem que você crie scripts usando várias linguagens para automatizar vários aspectos do seu processo de controle de versão. É um conceito simples, mas com uma estrutura subjacente um tanto complexa.

Nosso artigo mostra como usar técnicas avançadas para aproveitar ao máximo os Git hooks. Você pode usá-los localmente e do lado do servidor, torná-los dinâmicos usando parâmetros e variáveis, trabalhar com múltiplos repositórios remotos, e muito mais. Na verdade, a esta altura, sugerimos que os Git hooks se tornem sua arma secreta para aumentar a produtividade e a qualidade do código, e reduzir o tempo de conclusão do projeto.

Tem alguma dúvida sobre Git hooks e como usá-los? Conte pra gente na seção de comentários abaixo!

Jeremy Holcombe Kinsta

Content & Marketing Editor at Kinsta, WordPress Web Developer, and Content Writer. Outside of all things WordPress, I enjoy the beach, golf, and movies. I also have tall people problems ;).