Por que seu eu futuro vai agradecer por um histórico limpo.
Uma mensagem de commit é a única documentação que viaja com o código para sempre. Comentários são deletados, wikis ficam desatualizados, tickets são arquivados — mas git log é permanente. Equipes que escrevem bons commits conseguem navegar seu próprio histórico. Equipes que não fazem isso estão fazendo arqueologia em sua própria base de código em seis meses.
Um bom commit tem uma linha de assunto clara no modo imperativo ("Adicionar limitação de taxa ao endpoint de autenticação", não "Adicionada limitação de taxa" ou "coisa de limitação de taxa"), um corpo opcional que explica por que a mudança foi feita (não o quê — o diff mostra o quê), e contém exatamente uma mudança lógica.
fix: prevent duplicate webhook deliveries
The webhook dispatcher was firing on both the DynamoDB stream event
and the API Gateway trigger. Deduplicate by checking idempotency key
before dispatch.
Compare isso com o que a maioria dos repositórios realmente contém:
fix stuff
wip
updates
O primeiro commit é pesquisável, revertível e autodocumentado. O segundo conjunto é ruído. Daqui a seis meses, "corrigir coisas" não te diz nada — você terá que ler o diff, reconstruir o contexto e adivinhar a intenção. Os 10 segundos que você economizou escrevendo uma mensagem preguiçosa custam 10 minutos toda vez que alguém a encontra.
Conventional Commits adicionam um prefixo leve a cada assunto de commit que torna seu histórico legível por máquina sem sacrificar a legibilidade humana. O formato é simples:
feat: add dark mode toggle to settings
fix: correct timezone offset in standup scheduler
chore: upgrade TypeScript to 5.7
docs: add API rate-limit documentation
refactor: extract validation logic from route handler
O prefixo te diz a categoria da mudança de relance. feat significa novo comportamento visível ao usuário. fix significa que um bug foi corrigido. chore significa manutenção que não afeta os usuários. Isso não custa nada — você já está escrevendo uma linha de assunto, você está apenas adicionando 4–8 caracteres no início.
O retorno são changelogs automáticos, versionamento semântico (um feat aumenta a versão minor, um fix aumenta o patch), e filtragem instantânea (git log --grep="^fix:" mostra todas as correções de bug no último trimestre). Equipes que adotam Conventional Commits relatam que seus PRs são revisados mais rápido porque o revisor sabe que tipo de mudança esperar antes de ler uma única linha de diff.
Você não precisa de ferramentas para começar. Apenas concorde com os prefixos como equipe e os imponha na revisão de código. Adicione automação depois se quiser — mas a convenção é útil por si só.
Um commit deve representar exatamente uma mudança lógica. Não "tudo que fiz hoje", não "todos os arquivos que toquei para esta funcionalidade", e definitivamente não "WIP" — uma mensagem que não comunica nada e torna o commit não revertível sem efeitos colaterais.
Commits atômicos importam por duas razões práticas. Primeiro, revertibilidade: se um commit faz uma coisa, revertê-lo desfaz uma coisa. Se um commit faz três coisas e uma delas está quebrada, revertê-lo desfaz todas as três — incluindo as duas que estavam boas. Você está agora corrigindo danos colaterais do seu próprio rollback.
Segundo, bisectabilidade: git bisect faz uma busca binária no seu histórico de commits para encontrar qual commit introduziu um bug. É uma das ferramentas de depuração mais poderosas do Git — mas só funciona quando cada commit é uma unidade coerente. Se seus commits misturam mudanças não relacionadas, bisect vai te apontar para um commit que contém tanto a mudança culpada quanto três inocentes, e você está de volta a ler diffs manualmente.
O commit "WIP" é o inimigo de ambas as propriedades. Ele diz "eu não tinha terminado de pensar" — o que significa que o commit contém trabalho parcialmente completo que não pode ser revertido de forma limpa, não pode ser bisectado de forma significativa, e não pode ser entendido isoladamente. Se você precisa salvar trabalho em progresso, use git stash ou uma branch de rascunho. Não polua o histórico compartilhado com checkpoints que não têm valor semântico.
O teste da descrição do PR
Se você não consegue descrever seu commit em uma linha sem dizer "e", provavelmente são dois commits.