Clean Commits: boas práticas na escrita de mensagens de commit

Uma mensagem de commit no git é uma opção que temos ao criar um commit. Utilizando a opção -m no comando git commit, podemos atrelar uma mensagem ao commit criado. Esta mensagem, em geral, é utilizada para facilitar a identificação de cada commit, já que é muito mais fácil para um ser humano ler uma frase coesa do que a série aleatória de caracteres que constituem a identificação padrão de um commit.

Estas mensagens ficam salvas junto do commit, e podem ser vistas quando buscamos no histórico do repositório. No gitlab, pode ser visto no menu Code > Commits, enquanto pelo terminal podemos ver o histórico de commits com o comando git log. Algumas aplicações que possuem integração com o git (como o VSCode) costumam possuir interfaces para ver o histórico de commits. Além disto, a página principal de cada repositório possui uma coluna ao lado de cada arquivo e pasta mostrando qual foi o último commit que alterou aquele arquivo.

Ter mensagens claras e legíveis é, portanto, importante para facilitar uma boa documentação do desenvolvimento de um programa e facilitar a manutenção do código, principalmente em projetos que envolve diversos colaboradores. Neste artigo, veremos boas práticas para ajudar a manter um bom histórico de mensagens.

O problema

editar

Para um desenvolvedor, é muito comum escrever sem considerar que o código será lido por outras pessoas que não possuem a mesma compreensão do código que ele tem. Afinal, conseguir considerar se o que você escreveu é fácil de ser entendido por alguém que não tem o mesmo conhecimento que você é uma habilidade não trivial. Então, sem ter uma preocupação consciente com como estamos escrevendo, é fácil de ir pelo caminho mais simples de não escrever da melhor forma possível.

Porém, é comum que pessoas precisem ler o seu código sem ter um conhecimento completo. Às vezes, essa pessoa é o próprio desenvolvedor que escreveu o código, mas algum tempo no futuro. Portanto qualquer projeto pode sofrer com problemas na escrita e documentação.

Imagine que você vá se juntar a um projeto, e precisa ler o histórico de commits para entender como algumas mudanças foram feitas. Ou que você precisa voltar num código antigo para lembrar como um problema foi encontrado e resolvido. Você clona o repositório, abre o log de commits, e as mensagens de cada um dos commits são:

  • "v1"
  • "pequenas atualizações"
  • "."
  • "atualizando o git"
  • "melhorias na linha 52"
  • "major update"

Para você que está procurando alguma informação específica nos commits antigos, essas mensagens não são de auxílio algum. E todos os exemplos foram tirados de situações reais. As mensagens "v1" e "melhorias na linha 52" podem até dar uma pista para alguém que tem algum conhecimento prévio do projeto, mas se você está procurando alguma mudança específica, não é simples saber se ela foi implementada na versão "v1", ou se há 4 meses ela estava na "linha 52". Vocẽ precisaria procurar cegamente em cada um dos commits para tentar encontrar o que está procurando. Mensagens de commit são uma forma de documentação, e podem auxiliar no desenvolvimento de softwares.

Como melhorar?

editar

Se o leitor é familiar com os conceitos de Clean Code, grande parte das ideias a seguir são baseadas nestes conceitos, aplicadas para o caso das mensagens de commits. Para o leitor que não é, não são pré-requisitos para entendimento não texto. Alguns dos princípios não possuem uma aplicação direta, e outros precisam de uma certa abstração, mas eu entendo que são um bom ponto de partida.

Mas antes disto, acho necessário discutir o que, para mim, seria o Princípio 0.

Principio 0 - A caixa preta

editar

Antes de escrever algo bem, precisamos escrever algo. Para termos uma boa mensagem, precisamos ter uma mensagem. Isto pode parecer óbvio, mas olhemos para as mensagens "." e "atualizando o git". Estas mensagens poderiam ser apagadas e teríamos a mesma informação que temos agora. A idea deste princípio é pensar que você está rotulando uma caixa preta, que não sabemos o conteúdo sem o rótulo que a identifique. As outras não são muito melhores, mas pelo menos descrevem algo.

Mas evidentemente queremos rótulos melhores do que estes. Uma simples alteração é pensar que a sua caixa preta é única, e o rótulo dela deve representar o conteúdo único que está dentro dela. A mensagem "pequenas atualizações" poderia ser adicionada à uma infinidade de caixas diferentes. Se ela fosse escrita em algo como "pequenas atualizações no modelo de posição geográfica", já teríamos muito mais contexto definindo o que está ali dentro.

Este princípio foi incluído para lembrar ao leitor que é importante descrever o commit com alguma coisa, por mais simples que a atualização possa parecer. Afinal, ao olhar o histórico de commits, não costuma ser fácil saber se o commit "." alterou simplesmente um ponto que estava faltando numa separação de decimal, ou se incluiu dezenas de novas funções.

KISS - Keep it Simple, Stupid

editar

Este princípio, que pode ser traduzido como "Mantenha simples e estúpido", nos lembra que devemos evitar mensagens complexas de mais. Informação em excesso atrapalha uma busca quase tanto quanto a falta de. Quem nunca ignorou algo, só porque precisaria ler 1 parágrafo para entender, não uma frase. Descrições curtas e simples são melhores para identificar e ler, mas são mais complicadas de escrever.

Uma famosa frase (geralmente atribuída ao filosofo Blaise Pascal) é "Se eu tivesse mais tempo, teria escrito uma carta mais curta". Ele mostra a idea que é mais complicado transmitir uma ideia com poucas palavras do que muitas. Mas é justamente isto que devemos tentar fazer. Mas com cuidado, simplificar de mais uma mensagem pode perder informações importantes.

Nas mensagens acima, não vimos um exemplo de mensagens grandes de mais, afinal para o programador preguiçoso é mais simples escrever pouco do que muito. Mas isto pode acabar sendo um problema para o programador que exagera no preciosismo de sua escrita.

Diga não à funções grandes

editar

Neste princípio precisamos de certa abstração. Afinal, as funções em si pouco influenciam o tamanho da mensagem. O real ponto a se considerar é o tamanho dos commits que estão sendo feitos. Podemos entender como um commit "grande" aquele que poderia ser subdividido em partes menores, por exemplo, ou tratados como commits diferentes. Se você arrumou dois problemas diferentes do código, você pode subir ambos em um único commit, mas precisaria de uma mensagem maior, ou fazer dois commits diferentes cada um com sua mensagem. Isto ajudaria não só na legibilidade da mensagem, mas na procura da mudança desejada.

A organização de commits e branches é um tópico à parte, e que foge do escopo deste post. Mas um fator interessante a se pensar é que, se um commit demanda uma mensagem razoavelmente grande para ser devidamente descrito, é provável que você poderia ter estruturado de uma maneira diferente. Se é algo que não pode ser dividido em partes menores, ou se não é possível fazer múltiplos commits com facilidade (por exemplo, precisa da autorização de um administrador do repositório), pode ser mais interessante fazer um branch, guardar todos as mudanças em commits menores dentro deste branch, e depois só subir um merge. Assim, mantemos o histórico com logs menores, e evitamos fazer requisições constantes de merge ou push.

YAGNI - You Aren't Gonna Need It

editar

Este princípio tem bastante proximidade com o anterior. Ele pode ser traduzido como "Você não vai precisar", e com ele podemos pensar que não devemos incluir no commit mais do que o necessário para o commit. Por exemplo, você está subindo o commit com as "pequenas atualizações no modelo de posição geográfica" que exemplificamos anteriormente. Mas, ao incluir os arquivos, percebe que esqueceu de inclui no git um arquivo de configuração do esquema de cores do front end. Você pode incluí-lo no commit anterior, e ter duas informações completamente distintas no commit, o que demandaria provavelmente uma mensagem mais complexa; ou fazer dois commits separados cada um com sua mensagem. Quanto mais inclusões desnecessárias, mais arriscamos perder ou em legibilidade, ou em descritibilidade.

Este princípio também pode ser discutido como o princípio da "Responsabilidade Única": ter um commit que é responsável por uma determinada mudança facilita uma melhor escrita.

Favoreça legibilidade

editar

Este princípio é provavelmente o mais óbvio dentro do contexto, mas também o mais difícil de ser seguido conscientemente. É muito comum escrevermos com o intuito de favorecer a informação que está sendo passada. Mas toda a informação de um texto não tem valor algum se este texto não é lido de forma correta. Um texto fácil de ler é um texto que transmite mais informações.

Um aspecto da legibilidade, aqui, é pensar na forma do seu texto. Um log onde cada mensagem tem estrutura e formato diferentes, é um log mais demorado de ser lido. Se todas as mensagens seguem um formato padrão, é muito mais rápido de ler e encontrar alguma informação desejada.

Outro aspecto importante, é definir a língua na qual as mensagens estão sendo escritas. Nos exemplos iniciais, vimos a mensagem "major updates" no meio de outras mensagens em português. Se isto causou estranhamento no leitor, era a intenção. Não ter uma língua bem definida não só traz problemas na forma do texto, mas também causa problemas para qualquer um que não saiba falar todas as línguas que foram utilizadas. Mesmo escrevendo este post, eu fiquei em conflito se deveria mantes os nomes dos princípios que possuem abreviações em inglês, ou se deveriam aparecer traduzidos nos títulos. Manter uma consistência na escrita é importante para uma boa legibilidade.

Enfim, como melhorar?

editar

A verdade é que não há uma resposta exata. É fácil de ver quando estamos escrevendo mal, mas escrever bem é uma habilidade que pode tomar várias formas, e varia de pessoa para pessoa. Além disto, pessoas diferentes valorizam atributos diferentes. Eu, por exemplo, não me importo em colocar um ponto final ao final de cada mensagem de commit que eu escrevo, mas conheço pessoas que se incomodam muito com isto.

Mas, como um professor uma vez me disse, se você está escrevendo enquanto se preocupa em como está escrevendo, você provavelmente já está escrevendo melhor. Fora isto, a melhor forma de melhorar é prática constante. Escrever constantemente preocupado que outra pessoa vai ler o seu texto é a melhor forma de melhorar a forma em que escreve.

Apêndice: fechando issues com mensagens

editar

Enquanto escrevia este artigo, me deparei com a seguinte funcionalidade do git, que não entra totalmente no tópico do texto, mas é próxima o suficiente que achei interessante incluir.

O git dá a possibilidade de fechar issues em aberto por meio da mensagem do commit. Quando for escrever a mensagem, basta incluir na mensagem closes #[id]; , onde id é o número da issue no git, que pode ser encontrado na página da issue. Fazendo isto, o git salva não só quem fechou a issue, mas o commit que a fechou, com um hyperlink para o commit especificado. Você até pode fechar várias issues com a mesma mensagem, fazendo closes #[id_1], closes #[id_2], .... Existem outras keywords que podem ser utilizadas para o mesmo propósito, que podem ser conferidas na documentação.

O principal problema que essa funcionalidade trás é no quesito legibilidade. Estes diversos closes vão ficar poluindo as mensagens, e vão diretamente contra o princípio aqui discutido.

Referências

editar
  1. https://git-scm.com/docs/git-commit
  2. https://www.linkedin.com/pulse/principles-clean-code-dry-kiss-yagni-rajnish-kumar
  3. https://medium.com/@hlfdev/kiss-dry-solid-yagni-guia-simples-de-alguns-princ%C3%ADpios-de-clean-code-b3e4d9218c66
  4. https://slash.co/articles/how-to-write-clean-code-a-brief-guide-on-rules-and-principles/
  5. https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#close-an-issue