Git Hooks, o que são e como utilizá-los para descobrir commits duplicados?

Manollo Guedes
Equals Lab
Published in
5 min readMay 11, 2020

Desenvolver uma aplicação envolve diversos passos, indo desde o levantamento de requisitos, até as manutenções pós-entrega (sejam elas corretivas ou evolutivas).

Por vezes o desenvolvimento pode envolver passos repetitivos e cansativos, desse modo é interessante que possamos nos apoiar em ferramentas que possibilitem a automatização desses passos repetidamente burocráticos, mas tão necessários para a garantia da qualidade do nosso software.

Uma dessas ferramentas são os Git Hooks.

Git Hooks são scripts que possibilitam a execução de scripts tendo como gatilho alguns eventos relacionados ao Git.

“Não entendi, Manollo :/”

Ok, vamos lá.

Imagine que você esteja trabalhando com um processo de desenvolvimento que necessite de uma revisão de código de todos os pull-requests criados. E que dentro deste processo de revisão, você analise, além do código, a estrutura das mensagens de commit.

Para reduzir este processo podemos separá-lo em 2:

  1. Análise mecânica.
  2. Análise humana.

Revisar código não é algo que seja fácil de ser feito de forma automatizada, visto que muito mais que analisar estruturas de código é necessário avaliar a semântica do código quanto ao problema que ele pretende resolver. Porém, passar por cada um dos commits e verificar se eles seguem uma estrutura específica não é algo que precise ser feito por seres humanos. Convenhamos, isso é bastante chato!

Para isso podemos implementar Git Hooks que atuem antes mesmo do commit chegar no servidor, mas façam a análise da mensagem de commit do desenvolvedor no momento que ele realizar o commit.

No decorrer desta série de artigos, você vai aprender a fazer justamente isso :D

Mas antes disso, vamos falar um pouco de teoria, porque isso também é importante. Esse artigo foi dividido em dois. Ao final desse primeiro artigo você vai:

  • entender como usar Git Hooks;
  • descobrir alguns Git Hooks oferecidos pelo Git;
  • desenvolver um Git Hook capaz de reverter rebases que ocasionam duplicação de commits.

Com o segundo artigo iremos desenvolver um Git Hook que analisará a estrutura da nossa mensagem de commit e fará integração com o Jira (software de monitoramento de tarefas desenvolvimento pela Atlassian) para obter informações que melhorem nossas análises.

Como usar Git Hooks?

Git Hooks são shell scripts executados tanto a nível de cliente, quanto a nível servidor. Neste artigo focaremos nos client hooks.

Client hooks, como é bem previsível, são armazenados do lado do cliente dentro da pasta .git/hooks/ presente no diretório do repositório que você está trabalhando.

Como já foi dito, a execução dos hooks está atrelada aos comandos Git. E o Git consegue distinguir quando executar cada um dos hooks pelo nome que o arquivo recebeu. Isso significa que não adianta criar arquivos de hook com nomes mirabolantes como remover-commits-duplicados-na-branch-depois-de-fazer-rebase.sh. Não! Isso não vai funcionar. O Git só consegue saber qual shell script executar pelo nome que esse arquivo recebe.

Abaixo, temos uma lista com alguns dos hooks aceitos pelo Git e seus gatilhos.

  • commit-msg: hook disparado através do comando git commit. O shell script a ser executado por esse hook recebe como parâmetro o nome do arquivo que possui a mensagem de commit. O retorno deste Git Hook dita o prosseguimento ou não do commit por parte do Git. Caso o retorno seja diferente de 0, o commit será abortado.
  • pre-rebase: é invocado através do comando git rebase e é executado antes que o rebase seja realizado e possibilita, por exemplo, a prevenção de rebase em branches que não deveriam receber este tipo de ação. Esse hook recebe 2 parâmetros. O primeiro é o caminho do hook, o segundo é o nome da branch que está sendo usada como base para o rebase. Assim como o commit-msg, o retorno deste hook é quem dita o prosseguimento ou não com o rebase. Caso retorne algo diferente de 0, o Git irá abortar o rebase.
  • post-rewrite: é disparado após a execução de comandos que ocasionem uma reescrita na lista de commits como git rebase ou git commit --amend. Recebe como parâmetro o comando executado e, assim como os anteriores, ocasiona um aborto no comando executado no Git caso retorne algo diferente de 0.
  • post-merge: é invocado após um git merge, entretanto não é capaz de realizar ações que revertam o que foi feito pelo comando de merge.

Além desses hooks, o Git fornece muitos outros que podem ser consultados na documentação de Git Hooks.

Mãos a massa

Descobrindo commits duplicados usando Git Hook

Durante o processo de gerenciamento de versões, podemos incorrer no problema de duplicação de commits. Essas duplicatas geralmente são causadas por problemas no fluxo de trabalho com Git estabelecido pelo time de desenvolvimento.

Remover commits duplicados pode facilitar o gerenciamento de versões e consequentemente a manutenção do código.

Como o problema de duplicação ocorre geralmente pela execução de um rebase, o hook que será feito a seguir se refere ao gatilho post-rewrite.

O primeiro passo é recuperar as últimas mensagens de commit. Para isso executaremos o seguinte comando:

Após a recuperação dos commits, é preciso que selecionemos os commits duplicados.

Por fim, caso existam commits duplicados, basta avisar o desenvolvedor quais os commits que parecem estar com esse tipo de problema.

Com isso, ao executar um rebase que ocasione a duplicação de commits, receberemos um alerta que apresenta a mensagem dos commits duplicados e a quantidade de vezes que o commit aparece na nossa branch.

Terminal indicando a quantidade de vezes que cada commit está duplicado e a sua mensagem.
Mensagem informativa a respeito dos commits duplicados presentes na branch atual

É importante lembrar que para que o código funcione, ele precisa ser salvo com o nome post-rewrite (isso mesmo, sem a extensão .sh) dentro da pasta ./git/hooks e possuir permissão de execução.

Para dar essa permissão ao arquivo basta executar chmod +x post-rewrite.

Simples, não?

O código apresentado até aqui já se encontra disponível no GitHub.

No próximo artigo, veremos como usar os Git Hooks para nos conectarmos ao Jira e sermos capazes de tomarmos decisões com base nos dados das tarefas que estão recebendo os commits.

Confere lá: Integrando Jira e Git Hook para automatizar a validação de mensagens de commit.

Forte abraço!

Hérlon Manollo Cândido Guedes

--

--