Pular para o conteúdo
← voltar

@author é inútil

Por que o campo @author do Doxygen é um anti-pattern e o git blame resolve tudo que ele tenta resolver.

c embedded opinion

/**
* @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:

Google C++ Style Guide:

If you make significant changes to a file with an author line, consider deleting the author line.

Apache Software Foundation:

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.”

Drools (Red Hat):

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.