12k
All articles

Revisando Código Gerado por IA com Difftastic

Use o Difftastic para revisar código gerado por IA com diffs estruturais, integrá-lo ao git e separar mudanças de comportamento da formatação.

OpenReplay Team
OpenReplay Team
Revisando Código Gerado por IA com Difftastic

Ferramentas de codificação com IA frequentemente agrupam uma mudança real de lógica com uma reformatação completa em um único commit, e um git diff baseado em linhas afoga a única linha que altera o comportamento em uma tela cheia de vermelho e verde. O Difftastic é uma ferramenta de diff estrutural que analisa o código em árvores sintáticas e compara as árvores em vez do texto, de modo que reformatações puras, reajustes de linha e alterações de espaço em branco são registrados como nenhuma mudança — deixando apenas as edições que alteram o comportamento. Este artigo apresenta o que é o difftastic, como integrá-lo ao git e um fluxo de trabalho concreto para revisar os commits que um agente entrega a você.

Principais Conclusões

  • O Difftastic compara a árvore sintática abstrata via tree-sitter, de modo que reformatações e reajustes de linha aparecem como nenhuma mudança, enquanto um único argumento novo ainda aparece como uma alteração.
  • O Difftastic suporta mais de 30 linguagens e recorre a um diff orientado por linhas com destaque de palavras para extensões não reconhecidas ou arquivos com erros de análise sintática.
  • Integre-o com [diff] external = difft em ~/.gitconfig, e então leia o commit de um agente com git show <commit> --ext-diff. A configuração recomendada do git mudou no difftastic 0.61 (outubro de 2024), portanto copie-a diretamente do manual.
  • O Difftastic é uma ferramenta de diff externo, não um pager do git, portanto use-o em conjunto com o delta para visualização cotidiana e recorra ao difftastic para diffs de IA com muita reformatação.
  • difft --check-only --exit-code condiciona um commit à pergunta: “essa mudança alterou o comportamento, ou apenas a formatação?”

O problema: diffs de IA ocultam a linha que importa

Agentes e assistentes como Cursor, GitHub Copilot e Claude Code frequentemente reformatam uma função inteira — ou reajustam uma chamada longa em várias linhas — no mesmo commit que altera uma condição. Um diff orientado por linhas não tem como distinguir a diferença: ele marca cada linha tocada como alterada. Você obtém uma parede de vermelho e verde, e a única edição que altera o comportamento em tempo de execução está em algum lugar no meio. Revisar código gerado por IA é exatamente a situação em que a relação sinal-ruído mais importa, pois a reformatação é ruído gerado por máquina e a mudança de comportamento é aquilo pelo qual você é responsável ao fazer o merge.

O que é o difftastic?

O Difftastic é um diff estrutural que compara arquivos com base em sua sintaxe, e não em seu texto. Ele analisa cada versão com o tree-sitter, constrói uma árvore sintática abstrata e compara as árvores. A consequência prática: se você reformatar o código de modo que ele agora ocupe várias linhas, o difftastic mostra apenas o que realmente mudou, e um bloco movido ou renomeado é reportado como uma movimentação, em vez de uma exclusão seguida de adição.

O Difftastic é escrito em Rust, criado por Wilfred Hughes e é open source sob a licença MIT. Ele suporta mais de 30 linguagens de programação por meio de parsers tree-sitter — não as “50+” que algumas avaliações afirmam. Quando um arquivo possui uma extensão não reconhecida, ele regride graciosamente para um diff orientado por linhas com destaque de palavras, de modo que nada quebra em linguagens que ele não consegue analisar.

Instalar o difftastic e integrá-lo ao git

Instale o binário difft via gerenciador de pacotes ou cargo, e então registre-o como diff externo do git:

# macOS
brew install difftastic

# Rust toolchain (requer Rust 1.85+ a partir da versão 0.69)
cargo install difftastic

Para uso pontual, passe a configuração inline para não alterar nada permanentemente:

git -c diff.external=difft diff
git -c diff.external=difft show --ext-diff

Para tornar o difftastic seu padrão, adicione isto ao ~/.gitconfig, diretamente do manual:

[diff]
    external = difft

Isso faz com que o git diff use o difftastic; outros subcomandos então precisam apenas da flag --ext-diff, como git show --ext-diff e git log -p --ext-diff. A configuração recomendada mudou no difftastic 0.61 (outubro de 2024), portanto, se você estiver copiando um trecho de um blog mais antigo, substitua-o pela versão atual do manual. Prefira a saída inline em vez do padrão de duas colunas com --display inline:

difft old.js new.js --display inline

Por que o difftastic se destaca na revisão de código gerado por IA?

O diff estrutural foca nos nós de sintaxe alterados e elimina o ruído de edições não essenciais. A demonstração mais clara é o caso de reformatação com adição de um argumento. Suponha que um agente pegue uma assinatura de função em uma única linha e, por exceder o limite de comprimento de linha, um formatador a quebre em várias linhas — e o agente adicione um argumento:

// antes
function createUser(name, email) {}

// depois
function createUser(
  name,
  email,
  role,
) {}

Um diff de linhas destaca o bloco inteiro, pois cada linha mudou textualmente. O Difftastic destaca apenas o novo argumento role — a única edição que altera o comportamento. Esse é exatamente o tipo de adição sutil que um agente pode fazer passar despercebida por um revisor que está percorrendo um diff cheio de ruído. A mesma lógica se aplica a extrações: quando um agente move um bloco para um novo helper, o difftastic sinaliza o novo nome de função como adicionado, em vez de mostrar o wrapper e o corpo como um único e confuso par de exclusão e adição.

Um fluxo de trabalho de revisão de commits para saídas de agentes

Para ler apenas as mudanças semânticas que um agente produziu, aponte para o commit exato:

git show <agent-commit> --ext-diff
# ou revise o branch inteiro
git log -p --ext-diff main..agent-branch

Verifique três coisas: adições e remoções que o difftastic realmente sinaliza como mudanças; blocos reportados como movimentações ou renomeações em vez de reescritas; e qualquer hunk que reverta para um diff de linhas simples — esse é o sinal de que o difftastic encontrou uma extensão não reconhecida ou um erro de análise sintática. Por padrão, o difftastic recorre a um diff orientado por linhas sempre que erros de análise são encontrados, uma escolha conservadora para que ele nunca afirme que dois arquivos sintaticamente diferentes são iguais. Isso é importante para saídas de IA no meio de uma refatoração, que podem não ser analisadas corretamente; aumente a tolerância com export DFT_PARSE_ERROR_LIMIT=20 se um arquivo quase válido regredir desnecessariamente.

Para automação, o difftastic pode verificar se dois arquivos compartilham a mesma AST sem renderizar um diff:

difft --check-only --exit-code before.js after.js

Isso define o código de saída como 0 quando não há mudanças sintáticas e 1 quando há — uma verificação rápida para um hook de pré-merge ou etapa de CI que responde à pergunta: “o agente mudou o comportamento, ou apenas reformatou?”

Limitações e uso do difftastic em conjunto com o delta

É preciso ser honesto sobre as trocas envolvidas. O Difftastic escala relativamente mal em arquivos com um grande número de mudanças e pode consumir muita memória, portanto trate-o como uma ferramenta de revisão para commits específicos, e não como um substituto completo do git diff. Sua exibição lado a lado geralmente é boa, mas pode ocasionalmente causar confusão. É uma ferramenta de diff externo, não um pager do git, e não é renderizado dentro da aba de arquivos de PR do GitHub ou na maioria dos painéis de diff de IDEs — é uma ferramenta de linha de comando local.

A solução prática é usar ambos. Mantenha um pager de texto rápido para a visualização cotidiana e mude para o difftastic nos diffs pesados de reformatação.

FerramentaTipo de diffFunciona como pager?Melhor para
difftasticEstrutural (AST)Não (apenas diff externo)Diffs de IA com muita reformatação
deltaTexto com destaque de sintaxeSimDiffs do dia a dia
diff-so-fancyTexto embelezadoSimLimpeza leve

O Delta e o diff-so-fancy são baseados em texto; nenhum dos dois faz diff de AST. Use o delta como seu pager padrão e recorra ao difftastic quando o diff estiver afogado em ruído de formatação.

Um diff estrutural limpo é um filtro pré-merge: ele captura a linha que altera o comportamento antes que você aprove. As mudanças que ainda passam despercebidas — a edição sutil de lógica que um diff de IA cheio de ruído ocultou — são as que você acaba reconstruindo depois que elas entram em produção, e assistir a uma reprodução de sessão da interação com falha é uma das formas mais diretas de identificar esse tipo de regressão. Configure [diff] external = difft hoje, e então revise seu próximo commit de agente com git show <commit> --ext-diff e leia apenas o que realmente mudou.

Perguntas Frequentes

Qual é a diferença entre difftastic e delta?

O Difftastic é um diff estrutural que analisa o código com tree-sitter e compara árvores sintáticas abstratas, de modo que reformatações e reajustes de linha são registrados como nenhuma mudança. O Delta é um pager baseado em texto com destaque de sintaxe que ainda compara linhas. O Difftastic não pode atuar como pager do git e funciona apenas como ferramenta de diff externo, enquanto o delta funciona como pager para visualização cotidiana. Use o delta por padrão e o difftastic para diffs de IA com muita reformatação.

O que acontece quando o difftastic encontra um arquivo que não consegue analisar?

O Difftastic recorre a um diff orientado por linhas com destaque de palavras em dois casos: quando um arquivo tem uma extensão não reconhecida e quando encontra erros de análise sintática. O fallback por erros de análise é uma escolha deliberada e conservadora para que o difftastic nunca afirme que dois arquivos sintaticamente diferentes são iguais. Isso é importante para saídas de IA no meio de uma refatoração que podem não ser analisadas corretamente. Aumente a tolerância com a variável de ambiente DFT_PARSE_ERROR_LIMIT quando um arquivo quase válido regredir desnecessariamente.

O difftastic pode exibir diffs dentro da aba de arquivos de PR do GitHub?

Não. O Difftastic é uma ferramenta de linha de comando local que funciona como ferramenta de diff externo do git, e não como uma camada de renderização dentro da aba de arquivos de PR do GitHub ou da maioria dos painéis de diff de IDEs. Você o executa por meio de comandos como git show com a flag --ext-diff ou git log -p --ext-diff. Existem integrações de terceiros para algumas ferramentas como o magit, mas o suporte na aba de PR e em IDEs é limitado, portanto o difftastic é melhor tratado como uma etapa de revisão no terminal.

Como verifico se um commit de IA mudou o comportamento ou apenas reformatou o código?

Execute o difft com as flags --check-only e --exit-code nas duas versões de um arquivo. O Difftastic verifica se os arquivos compartilham a mesma árvore sintática abstrata sem renderizar um diff, definindo o código de saída como 0 quando não há mudanças sintáticas e 1 quando há. Isso é muito mais rápido do que um diff completo e cria uma verificação eficiente para um hook de pré-merge ou etapa de CI que distingue mudanças reais de comportamento de reformatações puras.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.