Claude Code alterou um arquivo que você não pediu? Como desfazer e evitar que aconteça de novo

tela do terminal mostrando como desfazer alterações do Claude Code usando rewind e git restore
Resposta rápida

Precisa desfazer alterações do Claude Code? São duas camadas. Dentro da sessão, o comando /rewind (ou Esc+Esc com o campo de prompt vazio) volta pra um checkpoint, e cada prompt enviado gera um, sem nenhuma configuração. O menu oferece três modos: restaurar código e conversa, só a conversa ou só o código. Só que o rewind cobre apenas o que as ferramentas de arquivo do Claude Code editaram na sessão: bash, edição manual, symlink e hard link ficam de fora. Aí o socorro é o Git, com git restore <arquivo> ou git checkout -- <arquivo>. E a prevenção é árvore limpa mais plan mode.

Fala aí, beleza? Você pede um ajuste pontual em UM arquivo, roda git status e aparecem seis arquivos modificados que ninguém mandou tocar 😅

Calma, isso tem conserto e nem é dos difíceis…

Existem dois caminhos pra desfazer alterações do Claude Code, e eles não competem: um vive dentro da própria sessão, com o /rewind, e o outro é o bom e velho controle de versão, que alcança justamente o que o rewind não alcança

A gente vai do socorro imediato até a parte chata (e mais importante): a rotina que faz essa cena não se repetir na próxima tarefa grande

Bora?

Sintoma 1: o Claude editou arquivos fora do pedido na sessão atual

O sintoma: o diff está muito maior que a tarefa

Você pediu pra ajustar uma função e o git status mostra config, teste, README e mais um punhado de coisa que não estava no combinado

Formação Claude Code
Formação Recomendada

Formação Claude Code

Domine Claude Code do absoluto zero até o avançado

  • 120 aulas
  • 4 projetos
  • 9h 45min

A causa: o agente amplia o escopo enquanto resolve o problema

Ele esbarra num import quebrado, decide arrumar, aí percebe que o teste depende daquilo, arruma também, e por aí vai

A boa notícia é que o Claude Code faz checkpointing automático, sem setup nenhum: cada prompt que você envia gera um checkpoint da sessão

É como ter um save do jogo antes de cada fase, sem precisar lembrar de salvar =)

Como voltar atrás com o /rewind:

O comando dedicado é esse:

/rewind

O mesmo menu abre pelo teclado, pressionando Esc duas vezes com o campo de prompt vazio

Detalhe que salva: com o input vazio, beleza? Se tiver texto digitado, o Esc faz outra coisa

Aí o menu te oferece três modos de restauração diferentes, e escolher errado aqui é o que faz gente achar que o rewind não funciona:

  • Restaurar código e conversa: volta tudo pro ponto anterior, o estado dos arquivos e o histórico do papo
  • Restaurar apenas a conversa: rebobina o histórico e MANTÉM o código como está agora
  • Restaurar apenas o código: volta os arquivos e mantém o histórico da conversa

O terceiro é o mais útil no caso clássico do escopo estourado: você quer os arquivos de volta ao que eram, mas quer manter o contexto da conversa pra dizer "refaz, só que mexendo apenas no arquivo X"

Como prevenir esse sintoma:

Olhe o diff ANTES de mandar o próximo prompt

git status
git diff

Parece óbvio, mas é o hábito que muda tudo: quanto mais prompts você empilha por cima de uma edição indesejada, mais trabalho vira separar o que presta do que não presta

Dois minutos de leitura de diff economizam meia hora de arqueologia depois

Sintoma 2: usei o /rewind e o arquivo continua alterado

O sintoma: você rodou o rewind, escolheu restaurar o código, e aquele arquivo teimoso continua modificado

A causa: o checkpointing não é onisciente

Ele rastreia apenas os arquivos alterados pelas ferramentas de edição do próprio Claude na sessão atual

O que fica DE FORA (e é bom decorar essa lista):

  • mudanças feitas via comandos bash, tipo os rm, mv e cp da vida
  • arquivos que você editou manualmente no seu editor
  • caminhos rastreados que sejam symlink ou hard link, que a restauração de código ignora

Ou seja: se o agente resolveu o problema com um mv no terminal em vez de uma edição de arquivo, o rewind passa reto por aquilo

A documentação de checkpointing do Claude Code é bem honesta nisso, vale a leitura

A solução: cai pro Git

Primeiro leia o que mudou de verdade:

git status
git diff caminho/do/arquivo

Depois descarte as alterações não commitadas daquele caminho específico:

git restore caminho/do/arquivo

Se você está numa versão mais antiga do Git, a forma clássica segue valendo:

git checkout -- caminho/do/arquivo

Tome cuidado! Os dois jogam fora a edição da árvore de trabalho

Se bater qualquer dúvida se aquilo prestava, não descarte: guarda primeiro (tem receita de stash mais abaixo)

Como prevenir esse sintoma:

Trate o checkpoint pelo que ele é: recuperação DENTRO da sessão

A própria doc orienta continuar usando controle de versão pra histórico permanente, commits, branches e colaboração

O checkpoint complementa o Git, não substitui

Na prática isso significa commitar antes de soltar tarefa grande, porque commit é a única rede que sobrevive ao fim da sessão

Rewind ou Git: o que cada um recupera

Não é escolher um lado, é saber qual ferramenta pegar em cada situação:

O que olhar Checkpoint do Claude Code Git
O que cobre Edições feitas pelas ferramentas de arquivo do Claude Code na sessão atual Qualquer alteração em arquivo versionado, com o estado commitado como referência
O que não cobre Mudanças via comandos bash (rm, mv, cp), edições manuais no editor, symlink e hard link Arquivo que nunca entrou no versionamento, já que não existe versão anterior pra voltar
Granularidade Por prompt enviado (um checkpoint por prompt) Por commit e por caminho de arquivo
Durabilidade Recuperação dentro da sessão Histórico permanente, branches e colaboração
Como aciona /rewind ou Esc+Esc com o input vazio git restore <arquivo> ou git checkout -- <arquivo>

Regra de bolso: aconteceu agora, na sessão, e foi o Claude editando arquivo? Rewind

Qualquer coisa fora disso, ou qualquer coisa que você queira que sobreviva a amanhã? Git

Sintoma 3: parte das mudanças presta e eu não quero perder tudo

O sintoma: o diff é misto

O ajuste que você pediu ficou bom, só que veio de carona uma edição em três arquivos que você não quer nem ver

Commitar assim mistura tudo num commit só, e desfazer tudo joga fora o trabalho bom junto

A causa: o reflexo de "desfaz tudo" é o errado aqui

Quando o diff é misto, você não separa por sessão, você separa por CAMINHO

Descartando só o que não interessa:

Rode o git restore apontando apenas os arquivos que sobraram:

git restore src/config/app.json README.md

O git restore chegou no Git 2.23.0, quando as responsabilidades do git checkout foram divididas em comandos mais específicos

Se conhece o git checkout -- <arquivo>, é a mesma ideia com nome mais claro do que faz

Tirando do staging sem perder a edição:

Caso o arquivo já tenha ido pro staging e você só queira tirá-lo de lá, mantendo as edições da árvore de trabalho intactas:

git restore --staged src/config/app.json

E se você quer restaurar os dois, index e árvore de trabalho, de uma vez:

git restore --staged --worktree src/config/app.json

Essa distinção é o que mais confunde a galera: --staged mexe no que vai pro commit, --worktree mexe no arquivo que está no seu disco

Guardando pra decidir depois:

Não tem certeza se aquela edição extra presta? Não descarte, guarde

Dá pra stashar apenas arquivos específicos passando o pathspec depois de dois traços:

git stash push -m "edicoes extras do agente" -- src/config/app.json

O suporte a pathspec no git stash push exige Git 2.13 ou superior

Como prevenir: revise arquivo por arquivo antes de aceitar, não o pacote inteiro de uma vez

Diff grande lido no atacado é diff não lido, sejamos honestos haha

Como evitar que se repita: rotina antes de soltar uma tarefa grande

Agora a parte que interessa de verdade, porque desfazer é remédio e isso aqui é vacina

  1. Comece com a árvore limpa

Commite ou stashe o que já estava pronto antes de abrir a tarefa grande:

git status
git stash push -m "wip antes da tarefa grande"

Assim, qualquer arquivo que aparecer no diff depois é obviamente do agente, sem investigação

O erro comum deste passo: soltar a tarefa por cima de meia dúzia de arquivos que você mesmo já tinha mexido, e depois não conseguir dizer quem fez o quê

  1. Rode a tarefa grande em plan mode

O Claude Code tem um modo de planejamento em que ele pesquisa, lê arquivos e propõe mudanças sem editar o código até você aprovar

Você alterna os modos com Shift+Tab, na ordem default, acceptEdits e plan

O erro comum deste passo: aprovar o plano no automático

O plano é o momento mais barato pra dizer "não mexe nessa pasta", aproveite

  1. Escolha o modo de permissão de forma consciente

Os modos disponíveis incluem default (que revisa cada ação), acceptEdits (que aprova edições de arquivo automaticamente), plan, auto e bypassPermissions

O erro comum deste passo: viver em acceptEdits porque cansou de aprovar coisa

É ali que a surpresa costuma nascer: o agente edita, você não vê, e o estrago só aparece no git status

  1. Isole trabalho arriscado em outra árvore de trabalho

O git worktree cria uma árvore separada, em outro diretório, ligada ao mesmo repositório:

git worktree add -b experimento-refactor ../projeto-refactor main

Se o agente aprontar, aprontou numa pasta que não é a sua principal

O erro comum deste passo: criar a worktree e continuar rodando o agente na pasta antiga, o que é praticamente arte performática

  1. Proteja arquivos sensíveis no settings.json

O settings.json do Claude Code aceita regras de permissão com padrões de caminho de arquivo, incluindo regras de deny pras ferramentas de edição

O bloco permissions tem listas allow, ask e deny, e as regras seguem o formato Ferramenta(padrão-de-caminho):

{
  "permissions": {
    "deny": [
      "Edit(**/arquivo.json)"
    ]
  }
}

O erro comum deste passo: configurar e nunca testar

Se você quer ir mais fundo nessa camada, vale ver como impedir edições fora do escopo na configuração

Como declarar o escopo de arquivos no pedido

Configuração é o cinto de segurança, mas quem dirige é o seu prompt

Boa parte da edição fora do alvo nasce de pedido vago, e isso se resolve no texto mesmo

Caso 1: nomear os caminhos que podem ser tocados

Frase pronta: "Ajuste a validação apenas em src/forms/checkout.ts. Não edite nenhum outro arquivo."

Por que funciona: você troca um objetivo ("arruma a validação") por um objetivo COM fronteira

Sem fronteira, o agente decide a fronteira sozinho, e a régua dele é o que resolve o problema, não o que você esperava

Caso 2: dizer explicitamente o que fica intocado

Frase pronta: "Não altere arquivos de config, migrations nem testes existentes."

Por que funciona: essas são justamente as pastas que o agente encosta "pra fazer funcionar"

Deixar a exceção escrita evita a interpretação criativa

Caso 3: pedir plano antes de edição quando a tarefa cruza pastas

Frase pronta: "Antes de editar qualquer coisa, me mostre a lista de arquivos que você pretende alterar e o motivo de cada um."

Por que funciona: você vê o escopo enquanto ele ainda é texto, e não diff

É o mesmo espírito do plan mode, só que escrito no pedido

Caso 4: pedir proposta em texto pro que estiver fora da lista

Frase pronta: "Se algo fora desses arquivos precisar mudar, escreva a sugestão na resposta em vez de aplicar."

Por que funciona: o agente continua útil (ele te avisa do import quebrado) sem virar dono do repositório

Caso 5: não deixar o objetivo aberto demais

Pedido genérico é convite pra escopo infinito

É o mesmo problema de pedir melhoria de performance sem métrica: sem alvo definido, qualquer arquivo vira candidato

Defina o quê, onde e o critério de pronto

E se liga: escopo aqui é linguagem do pedido

O reforço técnico continua sendo a regra de deny no settings.json, porque prompt é acordo e configuração é limite de verdade

Conclusão

São duas camadas, e agora você sabe qual puxar em cada caso

O /rewind (ou Esc+Esc com o input vazio) resolve dentro da sessão, com um checkpoint por prompt e três modos de restauração: código e conversa, só conversa ou só código

O Git resolve todo o resto: bash, edição manual, symlink, hard link, e principalmente o que precisa sobreviver ao fim da sessão

git restore <arquivo> pra descartar, git restore --staged pra tirar do staging, git stash push -- <caminho> pra guardar sem perder

Seu próximo passo, agorinha: roda um git status, deixa a árvore limpa, e abre a próxima tarefa grande em plan mode com os arquivos do escopo escritos no pedido

Depois disso, o git status deixa de ser fonte de sustos e vira só uma conferida rápida 😀

até o próximo post!

Perguntas frequentes

Existe atalho de teclado pra abrir o menu de rewind sem digitar o comando?

Existe sim. Com o campo de prompt vazio, é só apertar Esc duas vezes que o mesmo menu do /rewind abre. Detalhe importante: se tiver texto digitado no input, o Esc faz outra coisa, então o campo precisa estar limpo.

O rewind do Claude Code também desfaz comandos rodados no bash, tipo rm ou mv?

Não. O checkpointing rastreia só o que foi alterado pelas ferramentas de edição de arquivo do próprio Claude Code na sessão atual. Mudanças feitas via comandos bash (rm, mv, cp) ou editadas manualmente no seu editor ficam de fora, e quem resolve esse caso é o Git.

O /rewind funciona depois que eu fecho e abro o Claude Code de novo?

O checkpoint foi pensado como recuperação dentro da própria sessão, não como histórico permanente. A própria documentação do Claude Code orienta continuar usando Git pra ter commits, branches e um histórico que sobreviva além da sessão atual.

Qual a diferença entre git restore e git checkout — pra desfazer um arquivo?

O git restore é o comando mais novo, introduzido no Git 2.23.0 dentro da divisão de responsabilidades que antes ficavam todas no git checkout. A forma clássica git checkout — <arquivo> ainda é válida e faz o mesmo descarte das alterações não commitadas daquele caminho.

Dá pra guardar (stash) só um arquivo específico em vez de todas as alterações?

Dá sim, usando git stash push -m "mensagem" — caminho/do/arquivo, passando o caminho depois de dois traços. Esse suporte a pathspec no git stash push exige Git 2.13 ou superior.

O checkpoint automático do Claude Code também reverte symlinks e hard links?

Não. Na restauração de código, o Claude Code ignora caminhos rastreados que sejam symlink ou hard link. Se o seu projeto usa esse tipo de link, vale conferir manualmente depois de um /rewind.



Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares