Cada commit consiste em três elementos diferentes, sendo estes:
- Cabeçalho - Obrigatório, é basicamente o título do seu commit
- Corpo - Uma descrição mais extensa da informação o qual se pretende passar com seu commit
- Rodapé - Caso exista um ticket ou uma issue, você poderá informá-la aqui
Tanto o Corpo quando o Rodapé são opcionais, e até onde eu vejo geralmente não são muito utilizados.
O cabeçalho deve manter um padrão predefinido, contendo um tipo, um escopo (apenas quando cabível), e um título, e para uma leitura e compreensão mais rápida e simples, ele não deve passar de 50 caracteres.
{tipo}({escopo}): {titulo}
Exemplos:
fix(login redirect): prevent redirect to external url
feat(middleware): refuse connections from other hosts on production
refactor(markdown viewer): prepared for future viewer package change
fix: serve HomeOffline and remove SWR fetch
fix(query): performance with large offset
Esses exemplos foram selecionados da lista de commits do repositório oficial do TabNews.
Notaram como eles são simples e objetivos? Qualquer desenvolvedor que nunca tenha sequer visto o repositório antes na vida, ao ler esses commits já consegue ter uma mínima noção do que se trata o assunto, e esse é justamente o objetivo que quero atingir com este post!
Aqui está a verdadeira inspiração responsável pela minha decisão de escrever essa publicação.
O tipo do commit diz praticamente tudo sobre ele, sendo este capaz de informar se esse commit é relacionado a uma correção em uma linha de código, uma adição de nova feature, melhorias e entre outros.
O tipo deverá ser um dos listados abaixo:
- build: alterações que afetam o sistema de build e/ou dependências externas
- static: alterações no conteúdo de arquivos estáticos (dados .css, .js, .json, imagens, entre outros...)
- ci: alterações em arquivos e scripts de configuração de CI*
- cd: alterações em arquivos e scripts de configuração para CD*
- docs: alterações na wiki e/ou documentação da aplicação
- feat: uma nova feature ou recurso
- fix: referente a uma correção de bug da aplicação
- perf: alteração de código que melhora o desempenho da aplicação e não altera a forma como o usuário utiliza a aplicação
- refactor: refatoração de código, que não corrige um bug e nem altera a forma como o usuário utiliza a aplicação, apenas reescreve o código de maneira melhor organizada e estruturada
- improve: alguma alteração de código que melhore o comportamento de um recurso já existente
- style: alterações que não afetam o significado do código (espaço em branco, formatação/identaçaõ, ponto e vírgula, entre outros...)
- test: adicionando novos testes ou corrigindo testes existentes (normalmente não precisa se utilizar fix neste segundo caso)
- revert: reverter para um commit anterior
Além desses temos claro o famoso merge, que está em um padrão de estrutura diferente porém é gerado pelo próprio GitHub e nós compreendemos a importância dele da mesma forma!
*Observação importante: Hoje eu não tenho pleno conhecimento do que se tratam o CI (Continuous Delivery) e CD (Continuous Deployment). Por tanto se alguém já tiver ou quiser fazer um post a respeito, informe nos comentários a URL do post e ficarei orgulhoso em aprender sobre e também anexar nos dois itens marcados ali em cima!
Se o commit reverte a um commit anterior, ele deve começar por revert:
, seguido pelo cabeçalho do commit revertido.
Se o corpo for utilizado, ele deve informar: Isso revert o commit {hash do commit}
O escopo, de maneira bem resumida, é em quê exatamente você está trabalhando naquele commit, por exemplo um middlware, uma tela de login, um recurso específico, entre outros.
O título deverá conter uma descrição resumida e sucinta da mudança, e o ideal é seguir as regrinhas listadas abaixo:
- Use o imperativo, e no tempo presente e nunca no passado, por exemplo: "mudança", "alteração", "implementação", e nunca "mudou", "alterou", "corrigiu", etc
- Não capitalize a primeira letra, mantenha tudo em minúsculo exceto quando se tratar de um nome próprio, de um sistema ou linguagem (por exemplo MySQL, PHP), nestes casos mantenha o padrão do nome do que você está utilizando. Por exemplo: substituição da integração com o banco de dados MySQL pelo PostgreSQL
- Não utilize ponto final (.)
- Quando for necessário se referir a uma localização, função ou campo específico da aplicação, é recomendável utilizar a tag
code
referente a plataforma que está sendo usada, no caso do GitHub são as três crases (```)
Abaixo segue um exemplo completo:
fix(controller): use cf-connecting-ip
header to get client ip first
Uma descrição mais longa para seu commit pode ser fornecido logo após o título, em um campo separado, fornecendo informações contextuais adicoinais sobre o seu commit.
Quebre as linhas a pelo menos cada 72 caracteres, para uma melhor leitura.
Use essa descrição para explicar "o quê" e "por quê" essa alteração foi realizada, ao invés de "como".
O rodapé poderá ser fornecido abaixo de uma linha em branco após o corpo.
Você pode utilizar ele para referenciar um ticket no Jira, tarefa no Asana ou Perfex e outros helpdesks, ou mesmo uma issue no próprio GitHub, conforme o exemplo abaixo:
fixes issue #12
Essas são algumas possibilidades e vantagens que ganhamos ao realizar commits de maneira organizada e sucinta:
- Criação automatizada de CHANGELOGs
- Determina automaticamente um aumento de versionamento semântico com base nos tipos de commit utilizados
- Comunicar para outros colaboradores e interessados a natureza e motivo da alteração, de forma clara e padronizada
- Disparar processos de build e deploy
- Facilita a contribuição de outras pessoas em seus projetos, permitindo que eles explorem um histórico de commits mais estruturado e com uma melhor rastreabilidade e entendimento