Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA
LiçãoIniciantecódigo testado

Desfazer no Git: restore, reset e revert (qual usar)

Uma tabela de decisão para escolher entre restore, reset e revert conforme onde a mudança está, mais o reflog para recuperar o que parecia perdido de vez.

Rodolfo Mori4 min de leitura

Escolha como desfazer pela localização da mudança. restore atua em arquivos, reset move a referência e opcionalmente stage e working tree, e revert cria um commit que inverte outro. Antes de qualquer um, rode git status e confirme se a mudança está só no disco, preparada, commitada localmente ou publicada.

O sandbox começou com três commits reais:

bash
git --no-pager log --oneline -3
e26f0a6 feat: adiciona DDD 2f92a21 feat: adiciona Refatoração f9694ab feat: cria catálogo

Decida pelo estado, não pelo comando lembrado

estado intenção comando inicial o que pode se perder
edição não preparada descartar arquivo git restore arquivo edição local
conteúdo no stage retirar da seleção git restore --staged arquivo nada da working tree
último commit local ajustar git commit --amend hash antigo deixa a branch
commits locais mover a ponta git reset depende do modo
commit compartilhado compensar git revert HASH não apaga histórico
commit sem referência localizar git reflog registro recente pode expirar

Pense em três transparências: working tree, stage e commit. Restore troca o conteúdo de uma transparência por outra; reset reposiciona a referência e pode alinhar as camadas; revert desenha uma nova transparência com o efeito inverso. O limite é que arquivos e diretórios não são folhas físicas. Sempre confirme a documentação da opção escolhida.

Restore descarta uma edição ainda no disco

Uma linha de preço inválido aparecia apenas na working tree:

bash
git status --short
git restore catalogo.txt
git status --short
M catalogo.txt

A segunda execução de git status --short, depois do restore, não escreveu nada: a working tree ficou limpa.

O comando substituiu o arquivo pelo conteúdo do stage, que naquele momento coincidia com HEAD. Essa edição não havia sido commitada; o reflog não tem uma versão para recuperar. Revise git diff catalogo.txt antes de descartar.

Restore staged retira da caixa sem apagar a bancada

Depois de preparar um novo livro, a letra estava na coluna do stage. A opção --staged devolveu a seleção para HEAD, mas preservou o arquivo editado:

bash
git status --short
git restore --staged catalogo.txt
git status --short
M catalogo.txt M catalogo.txt

Esse é o comando quando você adicionou o arquivo errado. Você não precisa commitar nem apagar o trabalho. Depois selecione apenas os caminhos que pertencem à decisão correta.

Reset move branch, stage e talvez arquivos

Os modos mudam quantas camadas acompanham o novo HEAD. --soft move a branch e mantém o conteúdo preparado. O padrão --mixed move a branch e redefine o stage, preservando a working tree. --hard alinha os três e descarta alterações rastreadas da working tree.

bash
git reset --soft HEAD~1
git status --short
M catalogo.txt

Nesse cenário didático, o commit saiu da ponta e sua mudança permaneceu pronta para outro commit. Não execute sobre uma branch compartilhada sem entender que o hash deixa de ser ancestral da ponta publicada.

bash
git reset --mixed HEAD
git status --short
Unstaged changes after reset: M catalogo.txt M catalogo.txt

Agora a mudança ficou apenas na bancada. A palavra “mixed” não significa misturar commits; significa atualizar referência e índice, sem sobrescrever a working tree.

Revert preserva um erro que já faz parte da conversa

Quando o commit já foi enviado, criar uma compensação mantém o histórico que o time conhece. O teste reverteu o commit 49bc462:

bash
git revert --no-edit 49bc4626e41687945f4057751d90784166a3aa7b
[main 82b07af] Revert "feat: adiciona Arquitetura Limpa" Date: Mon Aug 24 21:43:13 2026 -0300 1 file changed, 1 deletion(-)

O log mantém causa e correção:

bash
git --no-pager log --oneline -3
82b07af Revert "feat: adiciona Arquitetura Limpa" 49bc462 feat: adiciona Arquitetura Limpa e26f0a6 feat: adiciona DDD

Revert pode conflitar se mudanças posteriores editaram a mesma região. Resolva como um merge: entenda o estado desejado, teste, prepare e continue. Não suponha que “inverter” sempre é uma subtração automática.

Amend corrige o último commit local

Se a mensagem ou um arquivo do último commit está errado e ninguém recebeu o hash, prepare a correção e recrie o commit:

bash
git add README.md
git commit --amend -m "docs: detalha instalação da livraria"
git --no-pager log -1 --oneline
[main d3d30de] docs: detalha instalação da livraria Date: Mon Aug 24 21:46:20 2026 -0300 2 files changed, 3 insertions(+) d3d30de docs: detalha instalação da livraria

O hash muda mesmo que você altere apenas a mensagem, porque ela faz parte do objeto. Depois de push, amend normalmente exige atualizar o remoto com história reescrita. A lição de rebase explica a regra de não reescrever o que outras pessoas já puxaram.

Reflog encontra a ponta que reset removeu

Para provar a recuperação, o laboratório moveu HEAD dois commits para trás:

bash
git reset --hard HEAD~2
HEAD is now at f9694ab feat: cria catálogo

O reflog registrou o local anterior:

bash
git --no-pager reflog -4
f9694ab HEAD@{0}: reset: moving to HEAD~2 e26f0a6 HEAD@{1}: commit: feat: adiciona DDD 2f92a21 HEAD@{2}: commit: feat: adiciona Refatoração f9694ab HEAD@{3}: commit (initial): feat: cria catálogo

Com o hash completo copiado da execução, a branch voltou:

bash
git reset --hard e26f0a60192f8adff054762ad2dcb222c52f3f61
HEAD is now at e26f0a6 feat: adiciona DDD

Isso recuperou commits porque os objetos ainda existiam. Não recuperaria uma linha nunca adicionada a commit ou stash. A prevenção continua melhor: git status, branch de segurança e backup antes de operações destrutivas.

Sua missão é criar um repositório descartável e demonstrar quatro casos: restore de working tree, retirada do stage, revert de commit e recuperação por reflog. Antes de cada comando, escreva qual camada muda. Termine quando o status confirmar sua previsão e você souber por que um push rejeitado não deve ser “resolvido” com reset ou force por impulso. Faça uma cópia do hash atual antes do exercício e compare o log depois de cada operação; essa referência torna visível quando o conteúdo foi preservado e quando o próprio histórico foi reescrito.

  • git
  • desfazer
  • reset
  • revert
  • restore
  • reflog

Perguntas frequentes

git reset --hard sempre pode ser recuperado pelo reflog?
O reflog costuma recuperar commits e movimentos recentes, mas não salva conteúdo que nunca foi commitado e suas entradas expiram. Não trate isso como garantia.

Dúvidas e comentários

Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.

Todo o código deste artigo foi executado em git version 2.54.0 (Apple Git-156) no macOS 27, e as saídas exibidas são as reais — como produzimos este conteúdo.

Fontes consultadas

  1. Git — git restore — git-scm.com
  2. Git — git reset — git-scm.com
  3. Git — git revert — git-scm.com

Continue por aqui