@author é inútil
Por que o campo @author do Doxygen é um anti-pattern e o git blame resolve tudo que ele tenta resolver.
/**
* @file following_service.c
*
* @brief Line following service.
*
* @author Lucas Haug <[email protected]>
* @author Daniel Nery <[email protected]>
* @author Felipe Bagni <[email protected]>
* @author Caio Souza <[email protected]>
* @author Vanderson Santos <[email protected]>
* @author Lucas Guedes <[email protected]>
* @author Henrique Matheus <[email protected]>
* @author Pedro Nogueira <[email protected]>
* @author Heloísa Apulcro <[email protected]>
* @author Henrique Apulcro <[email protected]>
* @author Pedro Machado <[email protected]>
*
* @date 06/2022
*/ Quem é o autor desse arquivo?
Essa é uma pergunta séria. Tem 11 nomes ali. Eu conheço cada um deles, porque esse arquivo é de um projeto da ThundeRatz, a equipe de robótica competitiva da Poli/USP, que tive (e ainda tenho) o prazer de contribuir por alguns anos. Mas se eu precisar entender uma decisão específica nesse código, pra quem eu pergunto? Pro Haug, que criou o arquivo em 2019? Pro Machado, que talvez tenha mudado três linhas? A resposta honesta é: esse header não ajuda em nada.
O campo @author do Doxygen é um daqueles padrões que a gente herda dos templates do projeto e nunca para pra questionar. Vou te mostrar por que você deveria.
O navio de Teseu
Existe um paradoxo filosófico antigo chamado Navio de Teseu: o herói grego Teseu tinha um navio que os atenienses preservavam como relíquia. Com o tempo, as tábuas apodreciam e eram substituídas por madeira nova. Quando todas as tábuas originais tinham sido trocadas, a pergunta era: ainda é o navio de Teseu?
Agora pensa no ciclo de vida de um arquivo de firmware numa equipe de competição. O Haug cria o following_service.c em 2019. Em 2020, o Daniel refatora a máquina de estados. Em 2021, o Felipe troca a estratégia de controle. Em 2022, mais três pessoas mexem em calibração, tratamento de erro e interface com sensores. Em 2023, alguém reescreve metade do arquivo pra adaptar a uma nova estratégia.
Nesse ponto, nenhuma linha original do Lucas sobreviveu. Mas o @author continua dizendo que ele é o autor. É o navio de Teseu: o arquivo ainda é “do Haug”?
E aí vem a questão prática: qual a política pra manter esse campo? Só o primeiro autor fica listado? Então a informação vira mentira com o tempo, como as tábuas do navio. Todos que mexeram são adicionados? Aí você chega nos 11 nomes que vimos acima, e a informação é igualmente inútil, porque não diz quem mexeu em que, quando, nem por que. É uma lista de presença, não um registro de autoria.
O dilema não tem solução boa dentro do @author:
- Se só o primeiro autor fica listado, você cai no navio de Teseu e a informação vira mentira silenciosamente.
- Se todos que mexeram são adicionados, o campo vira uma lista de presença que não diz nada de útil.
Nos dois casos, o @author falha exatamente no que ele promete fazer.
git blame resolve
Enquanto o @author tenta responder “quem é o autor desse arquivo?” (uma pergunta mal formulada), o git blame responde “quem escreveu essa linha?”, que é a pergunta que você realmente tem.
git blame -w following_service.c
Cada linha mostra o autor, a data e o hash do commit. Se alguém reformatou o código com clang-format e poluiu o blame, você tem opções:
# ignora mudanças de whitespace
git blame -w following_service.c
# ignora um commit específico (ex: reformatação em massa)
git blame --ignore-rev abc1234 following_service.c
# ignora permanentemente via arquivo de config
echo abc1234 >> .git-blame-ignore-revs
git config blame.ignoreRevsFile .git-blame-ignore-revs
Quer saber quem mais contribuiu pro arquivo? Não precisa ler um header desatualizado:
$ git shortlog -sn -- following_service.c
11 febagni
6 pedroazeredo04
4 DamaralHenrique
3 Caio Souza
3 Lucas
3 thor-the-rat
2 LucasHaug
2 guedeslucas1
1 Lucas-Gaspar-M
1 VanderSant
Só com isso você já tem uma visão bem diferente do que o header do Doxygen mostra. A ordem é por contribuição real, não por quem criou o arquivo. Tem gente no shortlog que nem aparece no @author, e vice-versa. Os números podem não ser perfeitos (se o arquivo foi renomeado ou movido, commits antigos podem não aparecer), mas mesmo assim é mais informação útil do que uma lista estática de nomes.
E o melhor é que é atualizado automaticamente, sem ninguém ter que lembrar de editar um comentário.
O git blame não é perfeito. Ele mostra quem fez o último commit que tocou uma linha, não necessariamente quem escreveu a lógica original. Mas as flags -w, --ignore-rev e -C (que detecta código copiado entre arquivos) resolvem a maioria dos casos. E qualquer IDE moderno mostra blame inline, como com o GitLens no VS Code e fugitive no Vim.
O que os grandes projetos dizem
Não sou só eu que acho isso. Olha o que os projetos e organizações que mais escrevem código no mundo dizem sobre @author:
If you make significant changes to a file with an author line, consider deleting the author line.
We discourage the use of author tags in source code… the version control system can be consulted to figure that out.
Linux kernel: não usa @author. Autoria é rastreada via Signed-off-by: nos commits, que serve como certificação legal de origem (Developer Certificate of Origin), não como tag decorativa num header.
Go: em 2022, removeu os arquivos AUTHORS e CONTRIBUTORS de todos os repositórios. Russ Cox, citando os advogados do Google: “The details of who owns what for copyright purposes are entirely independent of what the AUTHORS file says.”
Author tags in java files are a maintenance nightmare since a large percentage is wrong, incomplete or inaccurate.
JUnit 5: removeu @author tags antes do release Alpha. Na discussão da issue, Stefan Ludwig resumiu bem: “@author tags generally turn into lies.”
Comment rot: dados reais
Tem um estudo que quantifica isso. Pesquisadores mineraram 1.3 bilhão de mudanças no histórico completo de 1.500 projetos open source. Os números:
- Código e comentários evoluem juntos em apenas 7% dos casos (métodos) e 13% (classes).
- Ou seja: entre 80% e 93% das mudanças de código não atualizam os comentários correspondentes.
- Comentários inconsistentes com o código são 1.5x mais prováveis de introduzir bugs.
O @author é o caso mais óbvio de comment rot. Ele documenta um estado passado e ninguém tem incentivo (nem processo) pra mantê-lo atualizado. Pior: psicologicamente, a gente tende a confiar em comentários mesmo quando suspeita que estão desatualizados. Você vê @author Alice e vai atrás da Alice, que saiu da empresa há dois anos. Tempo perdido.
Quando faz sentido (sendo honesto)
Seria desonesto dizer que @author nunca faz sentido. Existem cenários legítimos:
- Código distribuído sem VCS: se você entrega firmware como tarball sem repositório git (ok boomer), a única forma de saber quem escreveu é o que está no arquivo.
- Compliance interno: algumas empresas têm políticas que exigem autoria em headers, independente de justificativa técnica.
- Licenças específicas: a EPL 1.0, por exemplo, exige que contribuidores se identifiquem como originadores da contribuição.
Mas mesmo nesses casos, um arquivo AUTHORS centralizado no root do projeto é melhor que @author espalhado em cada arquivo. Ele é mais fácil de manter, pode ser gerado automaticamente com git shortlog -sn --all > AUTHORS, e não polui o código.
E daí?
Coisas concretas pra fazer:
Tira o @author do template do seu projeto. Se o template gera um header Doxygen com @author pra cada arquivo novo, remove. Ninguém vai perder informação, porque o git já guarda isso.
Se alguém perguntar “quem escreveu isso?”, a resposta é git shortlog -sn -- arquivo.c, não um comentário que pode ou não estar certo.
Se o problema é saber quem é responsável por uma parte do código hoje (não quem escreveu historicamente), usa CODEOWNERS. Ele resolve um problema diferente e mais útil que o @author: não “quem escreveu”, mas “quem responde por isso agora”.
Sinceramente, não vejo nenhum ponto positivo pra esse campo de autor. Ele tenta resolver um problema que o git já resolve, resolve pior, exige manutenção manual que ninguém faz, e vira mentira com o tempo. O melhor que você pode fazer é parar de adicionar.