Claude Code reformatou o arquivo inteiro? Como pedir mudança cirúrgica e voltar a ter um diff revisável

Você pediu uma correção de três linhas e o Claude Code reformatou o arquivo inteiro: o diff virou um paredão ilegível e ninguém consegue revisar o que mudou de verdade. A causa costuma ser estrutural: a ferramenta Write sobrescreve o arquivo existente por completo, enquanto a Edit troca só o trecho, por substituição exata de string (old_string e new_string, sem regex). O resgate imediato é /rewind com Restore code, e repedir a mudança em modo plano com instrução precisa. A prevenção é hook de formatação, regra no CLAUDE.md e formatação sempre em commit separado
Um diff de 400 linhas para uma correção que cabia em 3
Fala aí, beleza? Se você abriu o git diff depois de pedir um ajuste bobinho e encontrou o arquivo inteiro pintado de verde e vermelho, você não fez nada de errado: isso tem causa técnica, tem resgate e tem prevenção
O problema é que um diff assim mata a revisão. Ninguém consegue dizer se a lógica mudou, se entrou algo fora de escopo ou se é só aspa simples virando aspa dupla
Neste post eu separo em três sintomas, cada um com causa e solução, e depois monto o fluxo de pedido cirúrgico pra isso não se repetir. Bora?
Sintoma 1: o diff mostra o arquivo inteiro alterado, mas a mudança real é de 3 linhas
O sintoma é fácil de reconhecer: todas as linhas aparecem como modificadas, o git diff rola por páginas e a mudança que você pediu está perdida no meio
A causa: Write x Edit
O Claude Code tem duas ferramentas diferentes pra mexer em arquivo, e a diferença entre elas é exatamente o que explica o paredão
A ferramenta Edit faz substituição exata de string: ela recebe um old_string e um new_string, sem regex e sem correspondência aproximada. O old_string precisa aparecer uma única vez no arquivo, senão o modelo amplia o trecho com o contexto ao redor ou usa replace_all: true pra trocar todas as ocorrências
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 116 aulas
- 4 projetos
- 9h 23min
A ferramenta Write escreve um arquivo no sistema de arquivos local sobrescrevendo o arquivo existente
Sacou? Não é o modelo "decidindo" mexer em 400 linhas. É Write reescrevendo o conteúdo inteiro, e o git comparando arquivo velho com arquivo novo do zero
Se você quer o raciocínio completo de pedido de mudança grande sem virar reescrita, dá uma olhada em refatoração sem reescrever o arquivo
A solução imediata: desfazer e repedir
O Claude Code tem checkpointing: ele captura o estado do código antes de cada prompt seu
Pra voltar, rode /rewind ou pressione Esc duas vezes com o campo de input vazio. O menu de rewind abre com as opções de restaurar código, restaurar conversa, ou ambos
Nesse caso você quer Restore code: o arquivo volta ao estado anterior e a conversa continua ali, com o contexto do que você já explicou
Aí você repete o pedido, agora nomeando o arquivo e a restrição em vez de soltar um "arruma isso"
Tome cuidado com o limite: os snapshots cobrem os 100 checkpoints mais recentes de uma sessão, e os checkpoints são apagados junto com as sessões após 30 dias. Não é backup, é rede de segurança de curto prazo
Como prevenir
A prevenção aqui é a forma do pedido. Em vez de descrever o resultado desejado do arquivo, descreva a troca: qual arquivo, qual trecho, qual restrição, e deixe explícito que o resto não deve ser tocado
Sintoma 2: só a indentação e as aspas mudaram, mas o diff conta como linha nova
Esse é o mais frustrante, porque a mudança é puramente cosmética e mesmo assim infla o diff. Uma linha recuada com 2 espaços virou 4, e pronto: linha removida, linha adicionada
Solução de leitura: mande o git ignorar espaço
Dá pra ler o diff filtrando o ruído de espaço em branco na hora da comparação
# ignora espaço em branco, inclusive quando uma linha tem espaço e a outra não
git diff -w
# mesma coisa, forma longa
git diff --ignore-all-space
# ignora só variação na QUANTIDADE de espaço
git diff -b
# ignora espaço no fim da linha
git diff --ignore-space-at-eol
Na prática o -w é o que salva a revisão: se o diff encolhe de 400 linhas pra 3 quando você roda com -w, você acabou de descobrir que a mudança real é minúscula e o resto é formatação 😀
Como prevenir: tire a formatação da mão do modelo
Se o formatador roda sempre, do mesmo jeito, o modelo não tem o que negociar em matéria de estilo
Um hook PostToolUse com matcher "Edit|Write" configurado em .claude/settings.json na raiz do projeto dispara apenas depois das ferramentas de edição de arquivo, e pode rodar um formatador automaticamente sobre o arquivo editado
Dá pra usar o jq pra extrair o .tool_input.file_path e passar pro prettier --write
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs -r npx prettier --write"
}
]
}
]
}
}
O ganho é que o estilo do arquivo passa a ser determinístico. Se todo arquivo já sai formatado do mesmo jeito, o diff da próxima edição não carrega diferença de estilo junto
Sintoma 3: correção e reformatação vieram no mesmo commit e o histórico ficou sujo
Aqui o estrago já saiu do working tree: um commit único misturando lógica e estilo
O problema não é estético. É que esse commit não dá pra reverter em partes: se a correção quebrou algo, você reverte a formatação junto. E na revisão de pull request, quem lê desiste na segunda tela
A solução: staging parcial com git add -p
O git add -p (ou git add --patch) permite staging parcial de arquivo: o git mostra o diff hunk por hunk e pergunta se você quer colocar cada trecho no stage
git add -p caminho/do/arquivo.js
Aí você vai respondendo hunk a hunk: entra a correção de lógica, fica de fora o ruído de formatação. Commita a lógica, depois commita o resto separado
O modo patch também existe em git reset --patch e git checkout --patch, então dá pra tirar coisa do stage ou descartar hunk específico com a mesma lógica
Como prevenir
Trate formatação como commit próprio e isolado desde o começo. Formatação nunca viaja de carona com correção de bug, e é isso
Se o Claude Code costuma encostar em arquivo que você nem citou, vale fechar o cerco antes: veja como limitar quais arquivos o modelo pode editar
Como pedir uma alteração cirúrgica ao Claude Code
O pedido vago é o que abre espaço pra reescrita. "Arruma esse arquivo" é convite pro modelo decidir o que é arrumar
Esse é o fluxo que dá ponto de veto antes de qualquer coisa tocar o disco:
- Entre no modo plano antes de pedir qualquer coisa. Pressione
Shift+Tabaté a barra de status mostrar o modo plano ativo, ou prefixe um único prompt com/plan. Nesse modo o Claude lê arquivos e propõe um plano, sem fazer edições até você aprovar
Erro comum deste passo: entrar no modo plano e mesmo assim escrever o pedido genérico. O modo plano te dá o veto, não a precisão
- Escreva a instrução precisa. A documentação oficial de boas práticas orienta referenciar arquivos específicos, citar restrições e apontar padrões de exemplo, porque quanto mais precisa a instrução, menos correções são necessárias
Na prática, isso significa três coisas no mesmo prompt: o caminho do arquivo, o que deve mudar, e o que não pode mudar
Erro comum deste passo: descrever o resultado final do arquivo em vez da troca. Descrever o arquivo inteiro é praticamente pedir um Write
- Leia o plano proposto antes de aprovar. Se o plano fala em reescrever, reorganizar imports ou padronizar o arquivo, recuse ali mesmo e ajuste o pedido, porque nada foi pro disco ainda
Erro comum deste passo: aprovar no automático, no piloto do enter. O modo plano só vale se você realmente ler
- Aprove e deixe a edição acontecer
- Revise o diff antes de dar a tarefa por concluída, checando se nada fora do escopo mudou. É aqui que o
git diff -wda seção anterior entra pra separar ruído de espaço de mudança real
Repare que nenhum desses passos é fórmula mágica de prompt. É só remover a ambiguidade e criar um ponto onde você consegue dizer não 🙂
Como separar formatação e lógica em dois passos revisáveis
A ideia é simples: dois commits, nunca um. Primeiro o estilo, depois a lógica
- Rode a formatação sozinha, no projeto todo ou no arquivo, e commite só isso. Nenhuma mudança de comportamento entra nesse commit
npx prettier --write caminho/do/arquivo.js
git add caminho/do/arquivo.js
git commit -m "style: formata arquivo.js (sem mudanca de logica)"
- Peça a mudança de lógica em cima da base já formatada. Como o arquivo já está no formato final, o diff da edição vai conter apenas o que importa
Erro comum deste passo: pedir a lógica antes de formatar. Aí os dois se misturam de novo e você volta pro sintoma 3
- Se os dois já se misturaram no working tree, fatie com
git add -pantes de commitar, separando os hunks de estilo dos hunks de lógica
- Registre o hash do commit de formatação em um arquivo
.git-blame-ignore-revsna raiz do repositório. É um arquivo com uma lista de hashes de commits que ficam escondidos da visualização de blame do GitHub
# commit de formatacao, sem mudanca de logica
9c1a2f0b5d3e4a7c8b1f2e6d0a4c7b9e1d3f5a80
O GitHub exclui essas revisões do blame quando o commit introduziu linhas novas ou modificou linhas existentes, e a interface mostra o aviso "Ignoring revisions in .git-blame-ignore-revs"
Localmente, dá pra usar direto ou deixar configurado de vez:
git blame --ignore-revs-file .git-blame-ignore-revs caminho/do/arquivo.js
# ou configura uma vez e esquece
git config blame.ignoreRevsFile .git-blame-ignore-revs
Erro comum deste passo: fazer o commit de formatação e esquecer de registrar o hash. Meses depois o blame de metade do arquivo aponta pro commit de estilo, e a autoria real das linhas some
Como deixar a regra registrada no CLAUDE.md para não repetir o problema
Corrigir um diff é resgate. Registrar a regra é prevenção
O CLAUDE.md é um arquivo markdown com instruções persistentes que o Claude Code lê no início de cada sessão. Ele carrega todo CLAUDE.md do diretório de trabalho e de cada diretório pai no lançamento, e carrega o arquivo de cada subdiretório sob demanda, quando lê arquivos ali
Ou seja: a regra que você escreve ali vale pra próxima sessão, e pra sessão depois dessa
- Gere o arquivo inicial com
/init, se o projeto ainda não tem um
- Refine com
/memory, que é o comando pra editar o conteúdo
- Escreva a regra em linguagem operacional, não em desejo vago. Algo no espírito de:
## Edicao de arquivos
- Prefira edicao pontual do trecho em vez de reescrever o arquivo inteiro
- Nao reorganize imports, indentacao ou aspas junto com uma correcao de logica
- Formatacao vai em commit separado, nunca junto da mudanca de comportamento
Erro comum deste passo: escrever a regra no chat, no meio da conversa, e achar que ficou valendo. Ela vale até a sessão acabar, e evapora. No arquivo, ela volta sozinha na próxima vez
Um aviso honesto: instrução em CLAUDE.md é instrução, não trava. Ela orienta o comportamento, não garante que nunca mais vai aparecer um Write. Por isso o hook e o modo plano continuam valendo
Quando o diff enorme é aceitável (e quando não é)
Nem todo diff gigante é problema. Às vezes reescrever o arquivo é exatamente o certo, e desfazer seria perder tempo
| Cenário | Diff enorme é aceitável? | Por quê |
|---|---|---|
| Migração de formatador no projeto todo | Sim | A mudança É de estilo, o commit inteiro tem um propósito só |
| Arquivo novo criado do zero | Sim | Não existe versão anterior pra comparar |
| Correção de bug | Não | O diff precisa mostrar a causa da correção, e só ela |
| Ajuste em arquivo com histórico de blame relevante | Não | Reescrita quebra a rastreabilidade de quem escreveu cada linha |
| Pull request que outra pessoa vai revisar | Não | Diff ilegível vira aprovação sem leitura, que é pior que não revisar |
A pergunta prática é: o tamanho do diff corresponde ao tamanho da intenção? Se você pediu uma coisa e o diff conta duas histórias, é hora do /rewind
Checagem final: revise o diff antes de considerar pronto
Antes de commitar ou abrir o PR, duas leituras
- Peça a revisão do diff a um subagente em contexto novo. A documentação oficial de boas práticas recomenda revisar o diff com um subagente em contexto limpo antes de dar a tarefa por concluída, verificando se nada fora do escopo da tarefa mudou
Erro comum deste passo: pedir a revisão na mesma conversa que fez a alteração. O contexto ali já está contaminado: quem escreveu tende a confirmar a própria decisão em vez de questionar
- Faça a leitura manual com o ruído filtrado
git diff -w
Se o que sobra depois do -w é o que você pediu, tá tranquilo. Se sobra coisa que você não pediu, alguém mexeu além do escopo e você acabou de pegar antes do commit
- Confirme o escopo dos arquivos: rode
git statuse veja se a lista de arquivos modificados bate com o que a tarefa exigia
Conclusão: o diff revisável é uma escolha de processo, não sorte
A lógica central do post é curta: Write sobrescreve o arquivo existente por completo, Edit troca só o trecho por substituição exata de string. Quando o diff estoura, quase sempre é essa diferença aparecendo
O modo plano te dá o ponto de veto antes de qualquer coisa tocar o disco
O hook PostToolUse e o CLAUDE.md tiram a formatação da negociação, cada um no seu nível: um no comportamento da ferramenta, outro na instrução persistente
E o git add -p com o .git-blame-ignore-revs garantem que, mesmo quando a bagunça acontece, o histórico não paga o preço
Se você quer sair daqui com uma ação concreta: abre o projeto agora, roda /init (ou /memory, se o arquivo já existe) e escreve a regra de edição pontual. Depois configura o hook PostToolUse com matcher "Edit|Write" em .claude/settings.json
Dois passos, e o próximo diff já sai revisável
até o próximo post! 😀
Perguntas frequentes
Por que o Claude Code reescreve o arquivo inteiro em vez de mudar só a linha pedida?
Porque ele tem duas ferramentas de edição diferentes. A Edit faz substituição exata de string, trocando só o trecho, enquanto a Write escreve o arquivo no sistema de arquivos sobrescrevendo o conteúdo existente por completo. Quando o modelo usa Write, o git compara arquivo velho com arquivo novo do zero e o diff aparece como se tudo tivesse mudado.
Como desfazer uma edição do Claude Code sem perder o histórico da conversa?
Rode /rewind ou pressione Esc duas vezes com o campo de input vazio para abrir o menu de rewind. Ali dá pra escolher Restore code, Restore conversation, ou os dois juntos. Escolhendo só Restore code, o arquivo volta ao estado anterior e a conversa segue com todo o contexto que você já tinha explicado.
Até quando dá pra recuperar um checkpoint do Claude Code?
O Claude Code guarda os snapshots de arquivo dos 100 checkpoints mais recentes de uma sessão. Esses checkpoints são apagados junto com as sessões depois de 30 dias, então não funciona como backup de longo prazo, só como rede de segurança de curto prazo.
Dá pra usar o CLAUDE.md pra impedir que o Claude Code mexa em formatação sem pedir?
Dá, e é o lugar certo pra esse tipo de regra: o CLAUDE.md guarda instruções persistentes do projeto, então o que você escreve ali continua valendo nas próximas sessões, diferente da regra solta no meio do chat, que evapora quando a sessão acaba. Escreva em linguagem operacional, do tipo não reorganize imports, indentação ou aspas junto com uma correção de lógica. Só lembre que é instrução, não trava, então o hook de formatação e o modo plano continuam valendo.
O git diff -w é seguro pra revisar mudança de lógica, ou só esconde espaço?
O -w (ou –ignore-all-space) ignora espaço em branco na comparação, inclusive quando uma linha tem espaço onde a outra não tem, mas não mexe em nada além disso. Se ainda sobrar diferença depois de rodar com -w, é mudança de conteúdo de verdade. Pra casos mais específicos existem -b, que ignora só a quantidade de espaço, e –ignore-space-at-eol, que ignora espaço no fim da linha.
Como limpar o git blame depois de um commit que só reformatou o arquivo?
O caminho é isolar a formatação em um commit próprio e registrar o hash desse commit numa lista de revisões ignoradas na raiz do repositório. Assim o blame deixa de apontar metade do arquivo pro commit de estilo e a autoria real das linhas continua visível. Se a correção e a reformatação já se misturaram no working tree, use git add -p pra separar os hunks antes de commitar.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares
Bateu o limite de uso do Claude Code? Como retomar a tarefa sem refazer tudo
Bateu o limite de uso do Claude Code? Veja como retomar a tarefa de onde parou com /usage, CLAUDE.md e --continue, sem refazer nada.
Como pagar o Claude Code no Brasil: cartão, dólar, IOF e quanto fica em reais
Claude Code preço Brasil na prática: câmbio, IOF de 3,5% e quanto fica na fatura. Planos Pro e Max convertidos em reais e como pagar com cartão.
Como instalar uma skill no Claude Code: passo a passo
Saiba como instalar skill no Claude Code: use a pasta pessoal para todas as sessões ou a pasta de projeto para versionar. Frontmatter YAML é obrigatório.
