Git notes: adicionando metadados a commits sem reescrever
1. O que são Git notes e por que usá-las?
Git notes são objetos especiais do Git que permitem anexar informações adicionais a commits sem alterar o hash SHA do commit original. Diferentemente de git commit --amend, que reescreve o histórico e modifica o identificador do commit, as notas são armazenadas em uma referência separada (refs/notes/) e associadas ao commit por meio de um ponteiro interno.
Essa característica é crucial porque:
- O SHA do commit permanece inalterado, preservando assinaturas GPG e referências externas
- Notas podem ser adicionadas, editadas ou removidas sem impactar outros desenvolvedores
- Permite enriquecer commits antigos com informações que não estavam disponíveis no momento da criação
Casos de uso típicos incluem:
- Anotações de revisão de código após o merge
- Metadados de CI/CD (status de build, resultados de testes)
- Documentação pós-commit (explicações tardias, links para issues)
- Informações de auditoria e conformidade
2. Criando e visualizando notas
O comando básico para adicionar uma nota a um commit é:
git notes add -m "Aprovado na revisão de código em 2024-01-15" abc1234
Para visualizar a nota de um commit específico:
git notes show abc1234
Para ver todas as notas associadas aos commits no log:
git log --notes
Você também pode adicionar notas a múltiplos commits de uma vez usando um loop no shell:
for commit in $(git rev-list main~5..main); do
git notes add -m "Commit revisado pelo time de QA" $commit
done
3. Editando, removendo e gerenciando notas
Para editar uma nota existente:
git notes edit abc1234
Isso abrirá o editor configurado. Se preferir substituir a nota diretamente pela linha de comando:
git notes add -f -m "Nova versão da nota" abc1234
Para remover uma nota:
git notes remove abc1234
Para listar todas as notas do repositório, mostrando o commit associado e o conteúdo:
git notes list
A saída típica mostra pares de hash (nota -> commit):
d1e2f3g4h5i6j7k8l9m0n1o2p3q4r5s6t7u8v9w0 abc1234def5678901234567890123456789012345
4. Notas como metadados estruturados
Notas não precisam ser apenas texto simples. Você pode armazenar JSON, YAML ou qualquer formato estruturado. Exemplo prático: adicionar resultado de testes automáticos a commits.
Adicionando uma nota com JSON:
git notes add -m '{"status": "passed", "coverage": 87.5, "duration_sec": 42}' abc1234
Para extrair e processar notas com scripts, use o comando git notes show combinado com ferramentas como jq:
git notes show abc1234 | jq '.coverage'
Exemplo em Python para processar notas de múltiplos commits:
import subprocess
import json
commits = subprocess.check_output(['git', 'rev-list', 'HEAD~10..HEAD']).decode().split()
for commit in commits:
try:
note = subprocess.check_output(['git', 'notes', 'show', commit]).decode()
data = json.loads(note)
print(f"Commit {commit[:8]}: status={data['status']}, coverage={data['coverage']}%")
except subprocess.CalledProcessError:
print(f"Commit {commit[:8]}: sem nota")
5. Compartilhando notas com a equipe
Por padrão, git push não envia notas. Para compartilhá-las com o repositório remoto:
git push origin refs/notes/*
Para receber notas de outros desenvolvedores:
git fetch origin refs/notes/*:refs/notes/*
Para configurar o comportamento automático, edite o arquivo .git/config ou use:
git config --add remote.origin.fetch "+refs/notes/*:refs/notes/*"
Agora, git fetch e git pull trarão as notas automaticamente.
6. Notas avançadas: namespaces e separação lógica
Você pode organizar notas em namespaces diferentes, cada um armazenado em uma referência separada. Isso é útil para separar contextos como revisão de código, CI e deploy.
Criando um namespace para revisões:
git notes --ref=reviews add -m "Aprovado após 3 rodadas de revisão" abc1234
Criando um namespace para CI:
git notes --ref=ci add -m "Build #4521 - Sucesso" abc1234
Para visualizar notas de um namespace específico:
git log --notes=reviews
git log --notes=ci
Para enviar apenas um namespace específico para o remoto:
git push origin refs/notes/reviews
Exemplo prático: separar notas de revisão de código de notas de deploy:
# Nota de revisão
git notes --ref=reviews add -m "Código revisado por Maria - sem problemas críticos" def5678
# Nota de deploy
git notes --ref=deploy add -m "Deploy realizado em produção em 2024-01-20 às 14:30 UTC" def5678
7. Limitações e boas práticas
Limitações importantes:
- Notas não são versionadas como commits. Se dois desenvolvedores adicionarem notas ao mesmo commit simultaneamente, podem ocorrer conflitos que exigem resolução manual.
- Em repositórios com milhares de notas, o desempenho do
git log --notespode degradar. Considere usar namespaces e filtrar apenas os necessários. - Notas não são incluídas em
git clonepor padrão — é preciso configurar explicitamente o fetch.
Boas práticas:
- Use namespaces para separar contextos claramente (reviews, ci, deploy, auditoria)
- Documente o formato das notas (JSON schema, campos obrigatórios) para a equipe
- Configure o fetch automático de notas no repositório compartilhado
- Evite notas para informações críticas que precisam ser imutáveis — prefira commits reais ou tags assinadas
- Limpe notas obsoletas periodicamente para evitar acúmulo desnecessário
Quando NÃO usar notas:
- Para informações que devem fazer parte do histórico imutável do commit (prefira
git commit --amendou um novo commit) - Para dados que precisam ser assinados criptograficamente (use tags GPG)
- Em workflows onde todos os desenvolvedores precisam ver as notas imediatamente sem configuração adicional
Referências
- Documentação oficial do Git - git-notes — Referência completa dos comandos e opções para gerenciamento de notas no Git.
- Git Notes: Adding Metadata to Commits — Tutorial da Atlassian explicando conceitos e exemplos práticos de uso de notas.
- How to Use Git Notes for Code Review — Artigo no Dev.to demonstrando como usar notas para anotações de revisão de código.
- Git Notes in Practice: CI/CD Metadata — Blog da Mergify mostrando casos reais de uso de notas para metadados de integração contínua.
- Advanced Git: Namespaces and Notes — Seção do livro Pro Git sobre referências internas, incluindo detalhes sobre namespaces de notas.
- Stack Overflow: How to push Git notes to remote — Discussão prática sobre como compartilhar notas entre repositórios remotos.
- Git Notes: A Hidden Gem for Developers — Artigo do freeCodeCamp explorando usos criativos e menos conhecidos das notas no Git.