← Blog · · Equipe ConvertCaseHQ · 8 min de leitura

Como escrever mensagens de commit do Git mais limpas e consistentes

Uma boa mensagem de commit do Git tem uma linha de assunto curta (mire em 50 caracteres) escrita no modo imperativo (em inglês, “Add” em vez de “Added”) e sem ponto final. Depois, uma linha em branco e um corpo quebrado em 72 caracteres que explica por que a mudança foi feita. Quanto às maiúsculas e minúsculas, escolha uma convenção e mantenha-a: com um prefixo como feat: ou docs:, a palavra seguinte costuma ser minúscula; sem prefixo, o conselho clássico é pôr maiúscula na primeira palavra.

Nada disso é imposto pelo próprio Git, e é por isso que os históricos vão se desviando. As regras de caixa e de modo verbal a seguir são convenções para mensagens escritas em inglês. Abaixo estão as regras, de onde cada uma vem e como fazer as suas ferramentas verificá-las, para você não precisar lembrar.

A anatomia de uma boa mensagem de commit

fix(editor): keep cursor position after paste

Pasting into an empty textarea moved the cursor to the start, because
the change handler replaced the value before restoring the selection.
Restore the selection after updating the value instead.

Fixes #142

Três partes: um assunto que diz o que o commit faz, um corpo que diz por quê e rodapés opcionais para referências e metadados. A própria documentação do Git recomenda começar com “a single short (no more than 50 characters) line summarizing the change, followed by a blank line and then a more thorough description” (uma única linha curta, de no máximo 50 caracteres, resumindo a mudança, seguida de uma linha em branco e depois de uma descrição mais detalhada). Tudo até a primeira linha em branco é tratado como o título do commit, que é o que git log --oneline, git shortlog e git format-patch mostram.

A linha de assunto: curta, no imperativo, sem ponto final

Cinquenta caracteres é um limite flexível. O guia SubmittingPatches, do próprio projeto Git, o chama exatamente assim e pede aos colaboradores que “skip the full stop” (omitam o ponto final). Se você não consegue ficar abaixo de 50, muitas vezes é sinal de que o commit faz duas coisas.

O mesmo guia pede que você “describe your changes in imperative mood” (descreva suas mudanças no modo imperativo), como se desse ordens ao código: “make xyzzy do frotz”, e não “makes xyzzy do frotz” nem “changed xyzzy to do frotz”. Um teste prático, das sete regras de mensagens de commit de Chris Beams: um bom assunto completa a frase “If applied, this commit will …” (se aplicado, este commit vai …).

  • “If applied, this commit will add CSV export” funciona.
  • “If applied, this commit will added CSV export” não funciona.
  • “If applied, this commit will bug fixes” também não, e não diz nada ao leitor.

O imperativo também combina com as mensagens que o próprio Git escreve por você, como Merge branch 'main' e Revert "…", então os seus commits se leem do mesmo jeito no log.

Maiúsculas no assunto: os dois campos

É aqui que os conselhos realmente entram em conflito, e a resposta certa depende de os seus assuntos começarem ou não com um prefixo.

ConvençãoExemploQuem recomenda
Sem prefixo, com maiúsculaAdd CSV exportA nota de Tim Pope, de 2008, sobre mensagens de commit; as sete regras de Chris Beams
Prefixo de área, minúscula depois deledoc: clarify sign-off rulesO SubmittingPatches do projeto Git
Prefixo de tipo, descrição em minúsculasfeat: add CSV exportAs diretrizes de commit do Angular; a configuração conventional do commitlint

A versão do projeto Git tem um detalhe que vale copiar. Só a primeira palavra depois do prefixo perde a maiúscula, e apenas por ser a primeira: palavras que sempre levam maiúscula continuam assim. O exemplo do próprio projeto é refs: HEAD is also treated as a ref, já que HEAD é sempre escrito em maiúsculas. A mesma lógica dá fix: handle iOS paste e docs: update README badges.

Nossa opinião, para mensagens em inglês: com prefixo, escreva a primeira palavra em minúscula, a menos que seja um nome ou uma sigla. Sem prefixo, use maiúscula. Misturar os estilos é o único erro de verdade, porque o git log --oneline transforma os seus assuntos numa lista, e uma lista que muda de caixa a cada poucas linhas parece descuidada. Para o mesmo raciocínio aplicado à documentação, veja o nosso guia sobre como escrever documentação consistente.

O que a especificação Conventional Commits realmente diz

A especificação Conventional Commits 1.0.0 define esta estrutura:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

As regras principais, em resumo:

  • feat (uma nova funcionalidade) e fix (uma correção de bug) são os dois tipos que a especificação define, e correspondem a versões MINOR e PATCH no Semantic Versioning, com as mudanças incompatíveis (breaking changes) correspondendo a MAJOR. Outros tipos são permitidos; a especificação menciona build, chore, ci, docs, style, refactor, perf e test, conforme recomendado pela configuração conventional do commitlint, que se baseia na convenção do Angular.
  • Uma mudança incompatível é marcada com ! antes dos dois-pontos (feat!: drop Node 16 support) ou com um rodapé BREAKING CHANGE:, e esse rodapé deve estar em maiúsculas.
  • As ferramentas que leem o formato não devem tratá-lo como sensível a maiúsculas e minúsculas, exceto no caso de BREAKING CHANGE. Sobre se os tipos devem ser minúsculos ou maiúsculos, o FAQ da especificação diz que qualquer caixa pode ser usada, “but it's best to be consistent” (mas o melhor é ser consistente).

A especificação não define um tamanho para o assunto nem exige o modo imperativo. Isso vem da convenção do Git.

Onde o commitlint é mais rigoroso que a especificação

O @commitlint/config-conventional, do commitlint, é a forma habitual de impor o formato, e seus padrões vão além da especificação. Passamos assuntos de exemplo pela versão 21:

AssuntoResultado
feat: add CSV exportPassa
feat: Add CSV exportFalha: o assunto não pode estar no estilo Frase (sentence case)
Feat: add CSV exportFalha: o tipo deve estar em minúsculas
fix: handle empty textarea.Falha: ponto final não é permitido
fix: README typoFalha: também conta como estilo Frase
fix: typo in READMEPassa

A linha do README é a que merece atenção. Um assunto que começa com uma sigla ou um nome de classe, como fix: README typo ou feat: URLSearchParams support, é rejeitado, embora o projeto Git aceitasse o equivalente. Reescreva para que a sigla não venha primeiro ou afrouxe a regra subject-case na sua configuração. O limite padrão do cabeçalho é de 100 caracteres, então o commitlint também não cobra os 50 de você.

O corpo: quebre em 72 e explique por quê

O Git nunca requebra a sua mensagem. A explicação de Tim Pope, de 2008, continua valendo: o git log recua as mensagens em quatro espaços, então, num terminal de 80 colunas, mais quatro por simetria à direita deixam 72 colunas, e o texto quebrado também continua legível quando os commits são enviados por e-mail com git format-patch. A nossa ferramenta Quebrar texto em N caracteres quebra um parágrafo em 72 caracteres nos limites das palavras, se o seu editor não fizer isso.

Use o corpo para o que o diff não mostra: o problema, por que esta correção e o que você tentou e não funcionou. Na linha de comando, cada -m vira um parágrafo próprio, então git commit -m "fix: keep cursor after paste" -m "Pasting into…" produz um assunto, uma linha em branco e um corpo.

Deixe as ferramentas fazerem a checagem

  • VS Code: defina "git.inputValidation": true. A caixa de commit então avisa quando o assunto passa de 50 caracteres (git.inputValidationSubjectLength) ou quando outra linha passa de 72 (git.inputValidationLength).
  • Vim: as configurações que acompanham o Vim para mensagens de commit quebram o corpo em 72 (textwidth=72) e param de destacar o assunto depois de 50 caracteres.
  • Um modelo de commit: git config commit.template ~/.gitmessage faz todo commit começar, no editor, com os seus lembretes.
  • Um hook commit-msg para verificações sem dependências. Salve isto como .git/hooks/commit-msg e torne-o executável:
#!/bin/sh
# Checks the subject line of every commit message.
subject=$(head -n 1 "$1")
length=${#subject}   # counts bytes in some shells; fine for ASCII subjects

if [ "$length" -gt 72 ]; then
  echo "commit-msg: subject is $length characters (limit 72, aim for 50)" >&2
  exit 1
fi
if [ "$length" -gt 50 ]; then
  echo "commit-msg: note, subject is $length characters (aim for 50)" >&2
fi
case "$subject" in
  *.) echo "commit-msg: drop the full stop at the end of the subject" >&2
      exit 1 ;;
esac
if [ -n "$(sed -n 2p "$1")" ]; then
  echo "commit-msg: leave line 2 blank, between subject and body" >&2
  exit 1
fi

Ele avisa quando o assunto passa de 50 caracteres, rejeita assuntos com mais de 72, um ponto final no fim ou a falta da linha em branco, e o git commit --no-verify o ignora quando você realmente precisa. Para uma contagem rápida antes de fazer o commit, cole o assunto no nosso Contador de caracteres.

O checklist, então: assunto no imperativo, uns 50 caracteres, sem ponto final, uma única regra de maiúsculas e minúsculas para o repositório inteiro, uma linha em branco, um corpo quebrado em 72 que explica por quê e um hook ou linter para que as regras sobrevivam a uma semana corrida.

© 2026 ConvertCaseHQ. Todos os direitos reservados.