Codeblox Blog

Padrões e práticas nos commits

Ted
22/04/2021

Por que boas mensagens de commit importam?

Uma mensagem de commit bem elaborada é a melhor forma de se comunicar sobre o contexto que ocasionou uma mudança de código, tanto para a equipe como para o próprio desenvolvedor futuramente, uma vez que relembrar o contexto de um trecho de código pode consumir tempo, além de que mensagens de commit ambíguas podem levar a erros de interpretação. O git diff nos mostra o que mudou no código, mas somente as mensagens do commit poderão nos dar a explicação do porquê da mudança.

A boa estruturação de mensagens de commit promove uma boa legibilidade do histórico de commits, tornando o uso de comandos como git log, shortlog, blame, revert e rebase mais úteis em aplicações como revisão de commits e pull requests, além de tornar mais fácil o entendimento de uma alteração de código ocorrida meses ou anos atrás.

Para criar um histórico de commits útil, a equipe deve concordar com uma convenção para mensagens de commit que contemple as características a seguir:


Estrutura básica para o commit:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

Exemplo:

docs(readme): adiciona título até 50 caracteres

O corpo da mensagem de commit é usado para maiores explicações,
apenas se necessário. Explique o problema que esse commit sana,
foque em 'porquê' você está fazendo essa mudança ao invés do 
'como' (isso pode ser visto no código). Existem efeitos colaterais
ou outras consequências não intuitivas dessa mudança? Aqui é
o lugar para falar disso.

Você pode criar mais parágrafos após linhas em branco. Limite a 
largura da linha por volta de 72 caracteres. A linha em branco 
que separa o título do corpo é crítica (ao menos que vc omita
inteiramente o corpo); ferramentas como 'log' pode se confundir 
caso as linhas estejam juntas.

 - Marcadores também são bem vindos
 
 - Normalmente se utiliza hífen ou asterisco para os marcadores,
   sendo precedido de um espaço, com linhas em branco entre eles,
   mas a convenção pode variar aqui
 
Referências a issues podem ser feitas no footer, dessa forma:

Resolves: #123
Ver também: #456, #789

Regras básicas para commits

  1. Especifique o tipo de commit

    Vários são as ações que podem ser desempenhadas em um código. Da convenção de commits do Angular, temos alguns tipos:

    • ci: Alterações em scripts e arquivos de configurações para integração contínua

    • docs: Todas as alterações em documentação

    • feat: Uma nova feature. Se correlaciona ao MINOR do Semantic Versioning

    • fix: Uma correção de bug. Se correlaciona ao PATCH do SemVer

    • BREAKING-CHANGE: Se correlaciona ao MAJOR do SemVer

    • perf: Uma alteração no código para otimizar performance

    • refactor: Uma alteração no código em que não adiciona uma feature nem corrige bug

    • style: Alterações em estilização ou em partes que não afetam o significado do código (espaço em branco, formatação, adicionar ponto e virgula que faltava, etc)

    • test: Adição ou correção de testes

  2. Separe título do corpo com uma linha em branco

    Da documentação do git commit:

    Though not required, it’s a good idea to begin the commit message with a single short (less than 50 character) line summarizing the change, followed by a blank line and then a more thorough description. The text up to the first blank line in a commit message is treated as the commit title, and that title is used throughout Git. For example, git-format-patch[1] turns a commit into email, and it uses the title on the Subject line and the rest of the commit in the body.

    Em primeiro lugar, nem todo commit precisa possuir título e corpo. Em muitos casos, uma linha é suficiente para descrever uma mudança, principalmente é tão simples que não precisa de contextualização adicional, por exemplo:

    Fix typo in introduction to user guide

    Nada mais precisa ser dito. Se o leitor estiver curioso sobre o erro, basta olhar na mudança em si, ou seja, usar git show, git diff ou git log -p.

    Entretanto, quando o commit precisa de maiores explicações e contextualização, vc precisa escrever um corpo. Exemplo:

    Derezz the master control program
       
    MCP turned out to be evil and had become intent on world domination.
    This commit throws Tron's disc into MCP (causing its deresolution)
    and turns it back into a chess game.
    

    O corpo da mensagem aparece no log de commits, o que pode ajudar muito na revisão do código. Além disso, a opção --oneline do git log pode ser usada pra exibir somente os títulos dos commits. O comando git shortlog é interessante por agrupar commits feitos por cada pessoa, além de exibir somente o título. Portanto, é muito importante o uso correto das linhas em branco.

    Mensagens com corpo não são fáceis de escrever com a opção -m. É melhor escrever em um editor de texto, que pode ser configurado para uso com git via linha de comando (o padrão utilizado é o Vim).

  3. Limitar o título a 50 caracteres

    Não precisa necessariamente ser 50 caracteres, é mais para ter uma noção de um tamanho que seja legível e força o autor a criar uma mensagem concisa e representativa para explicar a ação do commit.

    Dica: se você está tendo muita dificuldade para resumir a ação, você pode estar fazendo o commit de várias mudanças de uma só vez. Busque atomizar os commits.

    O próprio GitHub alerta quando é passado o limite de 50 caracteres e acaba truncando quando passa de 72. Então podemos considerar 72 caracteres como limite máximo e 50 caracteres como margem de segurança. No guideline do Angular é recomendado o limite máximo de 100 caracteres

  4. Capitalize o título de forma consistente

    Alguns guidelines, como do Angular, recomendam deixar a primeira letra do título em minúsculo. Já outros, recomendam deixar sempre maiúsculo. O importante nesse caso é escolher uma opção e ficar com ela.

  5. Não termine a linha do título com ponto

    Além de desnecessário, atrapalha a fazer uma mensagem abaixo de 50 caracteres. Da mesma forma, remova pontuações desnecessárias

    Use Corrige erro de digitação ao invés de Corrige erro de digitação.

  6. Use o modo imperativo no título

    O modo imperativo nada mais é do que falar ou escrever de forma a dar um comando ou instrução. Pode soar rude ao falar com pessoas, mas é perfeito para mensagens de commit: o próprio Git usa a forma imperativa como padrão quando um merge ou revert é feito. Então, quando se escreve em imperativo, acaba se seguindo a convenção do Git:

    Refatora subsistema X para leitura

    Atualiza a documentação

    Pode ser estranho a princípio, pois estamos acostumados a falar no indicativo, ou criar commits escritos como uma descrição dos seus conteúdos:

    Corrigido bug com Y

    Mais refatorações
    Para acabar com qualquer confusão, podemos estabelecer uma regra simples para ajudar a elaborar a mensagem. Um título de commit bem elaborado deverá sempre completar a seguinte frase sem perda de sentido: **Se aplicado, esse commit .**

    Exemplos:

    Se aplicado, esse commit atualiza a documentação

    Observe como não funciona em modos não imperativos:

    Se aplicado esse commit corrigido bug com Y

    Se aplicado esse commit mais refatorações

    Outras frases podem ser usadas. Da guia para commits do Go:

    This change modifies Go to <título do commit>

    Relembre: o uso do imperativo é importante apenas no título, apesar que os guidelines do Angular recomendam o seu uso no body.

  7. Limite a largura do corpo a 72 caracteres

    Git nunca quebra linha automaticamente. Quando vc escreve o corpo de uma mensagem de commit, vc deve ter lembrar da margem direita e quebrar as linhas manualmente

    A recomendação é de fazer em até 72 caracteres, para que o git tenha espaço para fazer suas indentações mantendo um máximo de 80 caracteres

  8. Use o corpo para explicar o que e porque x como

    Normalmente, o código é autoexplicativo. Porém o corpo do commit pode ser utilizado para dar mais detalhes e especificidades sobre uma correção, para explicar o comportamento esperado, para contextualizar a mudança do código, para dar informações adicionais sobre as implicações que aqueles trechos de código terão em outras partes do sistema, entre outros.


Mais exemplos e convenções

Tanto os guidelines do Angular a documentação do Conventional Commits defendem o uso da estrutura básica para commit:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

Dessas guidelines temos as recomendações:

Mais convenções e exemplos


Referências:

git


Ted Ribeiro
Ted Ribeiro
Desenvolvedor full stack .Net/Angular