Como renomear um padrão em dezenas de arquivos com o Claude Code sem perder o controle da mudança?

refatoração em massa no Claude Code para renomear um padrão em dezenas de arquivos com segurança
Resposta rápida

Refatoração em massa no Claude Code não é um pedido gigante: é lote pequeno, diff conferido e commit antes de seguir. Comece em modo plano (Shift+Tab até aparecer ⏸ plan mode on, ou claude --permission-mode plan), onde o Claude lê e propõe um plano sem editar nada em disco até a aprovação. Peça o inventário das ocorrências, fatie em lotes com critério de parada e rode um lote por turno. Se o lote sair errado, /rewind (ou Esc duas vezes com o input vazio) restaura código, conversa ou os dois. O Git segue como histórico permanente, checkpoint é só recuperação rápida de sessão 🙂

Você pede "renomeia esse padrão no projeto inteiro" e recebe de volta um diff com dezenas de arquivos mexidos de uma vez

Aí vem a parte chata: ninguém revisa isso de verdade

A gente rola o diff, bate o olho, aprova no susto e reza pra suíte de testes salvar

O ponto é que o Claude Code já tem as peças pra fatiar essa tarefa em pedaços auditáveis: modo plano pra planejar sem tocar em disco, checkpoint a cada turno, /rewind pra voltar, subagente pra varrer sem entupir a conversa e git worktree quando a coisa precisa rodar em paralelo

Neste post eu monto o fluxo completo de refatoração em massa no Claude Code, lote por lote, com conferência e commit no meio do caminho

O que você precisa antes de começar a refatoração

Antes de digitar o primeiro prompt, três coisas precisam estar no lugar

1. Um repositório com pelo menos um commit

Parece óbvio, mas é o tropeço clássico de quem começa o projeto do zero e já sai refatorando

Git worktree cria um checkout separado a partir de um commit existente, então num repositório sem nenhum commit a criação falha com Failed to resolve base branch "HEAD": git rev-parse failed

Sem commit também não existe ponto de retorno, e o Git é justamente o seu histórico permanente aqui

2. Árvore de trabalho limpa

Se já tem mudança sua pendurada no diff, você não vai conseguir separar o que o Claude fez do que você fez

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

Commita ou guarda o que estava pela metade, e só depois começa

3. As regras do padrão escritas no CLAUDE.md

Instruções persistentes de projeto ficam em CLAUDE.md ou .claude/CLAUDE.md no diretório de trabalho, e as globais em ~/.claude/CLAUDE.md

Os dois são carregados no início de toda conversa, então é ali que mora o combinado: qual é o padrão antigo, qual é o novo e o que NÃO pode ser tocado

## Refatoração em andamento

- Padrão antigo: `getUserData`
- Padrão novo: `fetchUserProfile`
- Não tocar em: `/legacy`, arquivos de migração, snapshots de teste
- Nunca renomear em mais de um diretório por turno

Escrever o padrão novo na mão é chato, e aqui vale o atalho de apontar um arquivo de referência do projeto em vez de descrever tudo por extenso

E se você quiser cercar mais ainda o raio de ação, vale lembrar de como as permissões de caminho funcionam: uma regra Edit(caminho) governa todas as ferramentas internas que escrevem arquivo, incluindo Write e NotebookEdit

Isso é importante porque uma regra Write(caminho) não é usada na checagem de permissão de arquivo, ou seja, quem limita o que ele pode editar é o Edit

Outra coisa pra não te pegar de surpresa: quando você aprova um comando com a opção de não perguntar de novo, essa aprovação vira regra de allow em .claude/settings.local.json

Vale dar uma olhada nesse arquivo antes de começar uma refatoração grande, pra saber o que já está liberado 😀

Passo a passo: renomear um padrão em dezenas de arquivos por lotes revisáveis

A lógica do fluxo é simples: o Claude nunca recebe a tarefa inteira de uma vez

Ele recebe um plano, e depois executa um pedaço desse plano por turno, com você conferindo no meio

1. Entre em modo plano e segure a vontade de já sair varrendo

O modo plano é ativado com Shift+Tab até a barra de status mostrar ⏸ plan mode on, ou já iniciando a sessão assim:

claude --permission-mode plan

No modo plano o Claude lê arquivos e propõe um plano, mas não edita nada em disco até você aprovar

E o primeiro pedido não é "renomeia", nem é "sai varrendo o projeto inteiro": é só abrir o assunto e deixar o terreno combinado

Vamos planejar a troca de getUserData por fetchUserProfile neste projeto.
Não varra o projeto inteiro agora e não edite nada.
O inventário das ocorrências vem no passo seguinte, de um subagente.
Por enquanto, confirme o que está escrito no CLAUDE.md sobre essa refatoração
e o que está marcado como zona proibida.

Por que segurar a varredura aqui? porque a conversa principal é o seu recurso mais escasso no meio de uma refatoração grande

O erro comum deste passo: achar que plan mode é "quase sem edição" e ficar com um pé atrás

Não precisa: em plan mode as ferramentas somente leitura funcionam como no modo padrão, e edições de arquivo nunca são auto-aprovadas, mesmo quando existe uma regra de allow que daria match

O erro de verdade é sair do modo plano no automático, sem ler o plano até o fim (a saída acontece aprovando o plano ou apertando Shift+Tab)

2. Delegue a varredura de mapeamento a um subagente

Varrer o projeto inteiro enche a conversa principal de busca, log e conteúdo de arquivo, e aí você perde contexto útil justo na hora de revisar

Por isso o inventário não sai da conversa principal, sai de um subagente: ele mantém contexto separado do agente principal e devolve apenas o resumo do trabalho

O detalhe que faz a diferença: a janela de contexto do subagente começa vazia (salvo quando é um fork), e o único conteúdo repassado do pai é a string de prompt

Ou seja, caminho de arquivo, padrão antigo, padrão novo e o que é proibido tocar precisam estar ESCRITOS no prompt do subagente:

Varra o diretório src/ deste projeto procurando o identificador getUserData.
Retorne apenas uma lista: caminho do arquivo, número da linha e o tipo da ocorrência
(definição, chamada, string, comentário).
Agrupe a lista por diretório.
Não edite nenhum arquivo. Não inclua trechos de código na resposta, só a lista.

O erro comum deste passo: mandar o subagente com um prompt do tipo "faz aquilo que a gente combinou"

Ele não viu a conversa, não sabe o que foi combinado 🙂

3. Defina os lotes e o critério de parada dentro do próprio plano

Com o inventário do subagente na mão, você decide o corte

Lote por diretório, por camada, por tipo de ocorrência, tanto faz: o que importa é que cada lote gere um diff que você consiga ler numa sentada

E cada lote precisa de um critério de parada explícito, senão o Claude "aproveita a viagem" e mexe no vizinho:

Lote 1: apenas src/services.
Renomear getUserData para fetchUserProfile em definições e chamadas.
Não alterar strings, comentários, testes ou qualquer arquivo fora de src/services.
Ao terminar src/services, PARE e me mostre o resumo do que mudou.

O erro comum deste passo: escrever o critério de parada só no chat e não no plano

O que está no plano aprovado é o contrato do turno, beleza?

4. Execute um lote por turno

Agora sim, aprova o plano e roda o lote 1

Um lote, um turno, e isso não é frescura: o checkpointing captura o estado do código antes de cada prompt que inicia um turno, rastreando as alterações feitas pelas ferramentas de edição de arquivo do Claude

Turno grande demais = checkpoint grosso demais pra voltar sem perder trabalho bom junto

O erro comum deste passo: emendar "aproveita e faz o lote 2 também" no meio do turno

Aí os dois lotes viram um diff só, e você acabou de reinventar o problema que veio resolver

5. Confira o diff do lote e commite antes do próximo

Antes de seguir, olho no diff de verdade:

git status
git diff

Se está certo, vira commit

git add src/services
git commit -m "refactor: renomeia getUserData para fetchUserProfile em src/services"

Esse commit por lote é a espinha do fluxo todo

A própria documentação posiciona os checkpoints como recuperação rápida em nível de sessão e orienta continuar usando controle de versão pra histórico permanente, commits e branches

Checkpoint não substitui Git, e é bom não confundir os dois papéis

O erro comum deste passo: rodar o lote 2 "só pra ver" antes de commitar o lote 1

Deu problema no 2, você volta e leva o 1 junto

6. Lote errado? Abra o /rewind

O menu de rewind abre com /rewind ou pressionando Esc duas vezes com o campo de entrada vazio

Tome cuidado com esse detalhe: se houver texto digitado, o duplo Esc apenas limpa o campo

O menu lista os prompts enviados na sessão e oferece quatro ações:

  • Restore code and conversation: volta os dois
  • Restore conversation: volta só o papo, o código fica como está
  • Restore code: volta só os arquivos
  • Summarize from here: resume a partir daquele ponto

Na refatoração por lotes, o mais útil costuma ser voltar o código do lote que deu ruim e manter a conversa, porque o mapeamento que o subagente devolveu continua valendo

O erro comum deste passo: tratar o /rewind como rede de segurança definitiva

Ele é recuperação de sessão, o histórico permanente é o Git

7. Opcional: hook PostToolUse pra passar o formatador em cada arquivo editado

Rename em massa costuma bagunçar import e quebra de linha

Dá pra configurar um hook PostToolUse em .claude/settings.json com matcher Edit|Write pra rodar um comando (formatador ou linter, por exemplo) sobre o arquivo editado, extraindo o caminho do arquivo do payload:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs -r seu-formatador"
          }
        ]
      }
    ]
  }
}

O erro comum deste passo: esperar que o hook sirva de freio

Hooks PostToolUse não conseguem desfazer ações, porque disparam depois que a ferramenta já executou

Ele limpa a sujeira, ele não impede a sujeira

8. Opcional: salve o fluxo como skill pra reusar

Se esse vaivém de lote virou rotina no seu projeto, empacota

O formato recomendado hoje é .claude/skills/<nome>/SKILL.md, que também é invocável como /nome (o diretório .claude/commands/, escopo do projeto, e ~/.claude/commands/, pessoais, são o formato legado e seguem funcionando)

Comandos personalizados aceitam argumentos dinâmicos via placeholders, com campos de frontmatter como allowed-tools, description, model e argument-hint:

---
description: Renomeia um padrão por lotes revisáveis
argument-hint: <padrao-antigo> <padrao-novo>
---

Delegue a um subagente a varredura das ocorrências de $1 no projeto,
pedindo só a lista de caminho, linha e tipo de ocorrência, agrupada por diretório.
Com esse retorno, proponha lotes de renomeação de $1 para $2, um diretório por lote,
com critério de parada explícito em cada lote.
Não edite nada até eu aprovar o plano.

Aí a próxima refatoração começa com /renomear-lote getUserData fetchUserProfile e você já cai no fluxo certo

Quando o controle escapa: problemas comuns na refatoração em massa

As opções de restaurar código não aparecem no /rewind

Sintoma: você abre o menu e só vê restaurar conversa, resumir e cancelar

Causa: as duas opções de restaurar código só aparecem quando o checkpoint selecionado tem alterações de arquivo rastreadas pra reverter

Se não houve edição capturada depois daquele ponto, não tem o que voltar

Solução: suba um checkpoint (ou mais de um) até achar o prompt que de fato iniciou o turno com as edições

Prevenção: um lote por turno, sempre

Quando cada turno tem um conjunto claro de edições, achar o ponto de retorno é trivial

O /rewind não desfez as mudanças

Sintoma: você restaurou o código e os arquivos continuam com o conteúdo novo

Causa: uma skill "forked" rodando em background aplica edições fora dos checkpoints da sessão, então o /rewind não desfaz essas mudanças

Solução: a saída aqui é o Git mesmo, voltando pro último commit bom do lote

Prevenção: commit por lote (é, de novo esse) e atenção ao que você deixou rodando em background durante a refatoração

Sintoma: restaurou tudo, mas um punhado de caminhos ficou pra trás

Causa: o checkpointing não reverte arquivos que são symlink ou hard link

Ao restaurar código, esses caminhos são pulados e mantêm o conteúdo atual

Solução: trate esses caminhos na mão, pelo Git

Prevenção: se o projeto usa link pra compartilhar arquivo entre pastas, deixa isso escrito no CLAUDE.md como zona de atenção antes de sair renomeando

Sessão longa perdeu os checkpoints antigos

Sintoma: você quer voltar num ponto lá do começo do dia e ele não está mais no menu

Causa: o Claude Code mantém snapshots de arquivo para os checkpoints mais recentes da sessão, com limite documentado de 100 checkpoints mais recentes por sessão

Solução: Git, sempre Git

Prevenção: essa é a prevenção transversal do post inteiro: commit a cada lote conferido

Com commit por lote, o pior caso nunca é "perdi a refatoração", é "refaço um lote"

Quando vale usar lotes, subagente ou worktree separado

Nem toda refatoração pede o arsenal completo

Dá pra escolher o recurso pelo tamanho e pelo formato da tarefa:

Cenário Recurso que pede Por que
Rename pequeno e contido, um ou dois diretórios Lotes na sessão principal O diff cabe na sua revisão e o checkpoint por turno já te cobre
Varredura ampla, muitos diretórios e muitos falsos positivos Subagente de mapeamento Roda em contexto próprio e devolve só o resumo do trabalho, sem poluir a conversa com buscas, logs e conteúdo de arquivo
Refatoração rodando em paralelo com outra frente de trabalho Git worktree Cada worktree é um checkout separado na própria branch, criado a partir de um commit existente, então edições simultâneas não colidem
Refatoração que atravessa dias /resume As conversas ficam salvas localmente e o comando lista sessões anteriores pra você escolher qual continuar

O caso do worktree é o que mais gente ignora

Se você vai tocar o rename enquanto outra frente mexe nos mesmos arquivos, não adianta disciplina de lote: as duas edições se atropelam no mesmo checkout

E o caso do /resume é o mais subestimado 😀

Refatoração grande raramente acaba no mesmo dia, e retomar a sessão certa é bem melhor que reexplicar o padrão do zero pra uma conversa nova

Conclusão

A régua da refatoração em massa é curta e não muda: lote pequeno, diff conferido, commit antes de seguir

Modo plano pra enxergar o tamanho do problema sem mexer em disco, subagente pra varrer sem entupir a conversa, checkpoint e /rewind pra recuperar o turno que saiu torto, worktree quando a coisa roda em paralelo

O próximo passo é bem concreto: abre o CLAUDE.md do projeto, escreve o padrão antigo, o padrão novo e a lista do que não pode ser tocado

Depois entra em modo plano e roda só o primeiro lote

E mantém o combinado na cabeça: Git é o histórico permanente, /rewind é só a recuperação rápida da sessão

Deu ruim? volta um lote, não o projeto inteiro

até o próximo post!

Perguntas frequentes

Como usar o /rewind para desfazer só o último lote da refatoração sem perder a conversa inteira?

Abra o menu com /rewind ou Esc duas vezes com o campo de entrada vazio e escolha Restore code, que reverte só os arquivos daquele checkpoint e mantém o histórico da conversa. Isso funciona porque o checkpoint é criado a cada prompt que inicia um turno, então cada lote vira um ponto de retorno separado. Se aquele checkpoint não tiver alteração de arquivo registrada, o menu nem oferece essa opção, só Restore conversation, Summarize from here e cancelar.

Existe limite de quantos checkpoints o Claude Code guarda numa refatoração que passa por vários lotes?

Sim, o limite documentado é de 100 checkpoints mais recentes por sessão. Numa refatoração de dezenas de arquivos dividida em lotes pequenos isso raramente é um problema, mas em sessões muito longas vale considerar dar /resume numa sessão nova de tempos em tempos. De qualquer forma, checkpoint é recuperação rápida de sessão, não substitui o commit no Git para guardar o histórico permanente.

O que acontece se um dos arquivos que precisam ser renomeados for um symlink?

O checkpointing não reverte arquivos que são symlink ou hard link, então ao restaurar código esses caminhos são pulados e ficam com o conteúdo atual. Isso importa porque se um lote mexer nesse tipo de arquivo, o /rewind não vai limpar aquela edição sozinho. Nesses casos, quem resolve é o Git mesmo, revertendo o arquivo manualmente.

Dá pra rodar um linter automaticamente depois que o Claude renomeia cada arquivo do lote?

Dá, configurando um hook PostToolUse em .claude/settings.json com matcher "Edit|Write" apontando pro comando do formatador, e o Claude Code extrai o caminho do arquivo editado do próprio payload. O detalhe é que esse hook roda depois que a edição já aconteceu, ele não tem como bloquear ou desfazer nada. Ou seja, ele ajuda a manter o padrão de formatação, mas não substitui a conferência do diff antes de aprovar o lote.

Vale a pena usar git worktree para rodar dois lotes de renomeação ao mesmo tempo?

Vale quando os lotes tocam diretórios totalmente diferentes, porque cada worktree é um checkout separado numa branch própria, criado a partir de um commit existente, e isso evita que as duas sessões colidam no mesmo arquivo. O pré-requisito é ter pelo menos um commit no repositório, senão a criação do worktree falha com o erro de resolução da branch base. Se os lotes mexem em arquivos que se cruzam, é mais seguro seguir sequencial mesmo, um lote por vez com commit no meio.

Dá pra transformar esse fluxo de refatoração em lotes num comando que eu reuso em outros projetos?

Dá, criando um comando personalizado em .claude/commands/ para o projeto ou em ~/.claude/commands/ para valer em todos os projetos, sendo esse o formato legado que ainda funciona. O formato recomendado hoje é .claude/skills/<nome>/SKILL.md, invocável também como /nome, e ambos aceitam placeholders como $1 e $2 pra você passar o padrão antigo e o novo na hora de chamar. Assim o prompt de inventário e o de lote viram um comando único em vez de digitados toda vez.



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