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.
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:
git --no-pager log --oneline -3Decida 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:
git status --short
git restore catalogo.txt
git status --shortA 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:
git status --short
git restore --staged catalogo.txt
git status --shortEsse é 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.
git reset --soft HEAD~1
git status --shortNesse 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.
git reset --mixed HEAD
git status --shortAgora 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:
git revert --no-edit 49bc4626e41687945f4057751d90784166a3aa7bO log mantém causa e correção:
git --no-pager log --oneline -3Revert 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:
git add README.md
git commit --amend -m "docs: detalha instalação da livraria"
git --no-pager log -1 --onelineO 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:
git reset --hard HEAD~2O reflog registrou o local anterior:
git --no-pager reflog -4Com o hash completo copiado da execução, a branch voltou:
git reset --hard e26f0a60192f8adff054762ad2dcb222c52f3f61Isso 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.
Perguntas frequentes
git reset --hard sempre pode ser recuperado pelo reflog?
Dúvidas e comentários
Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.
Entrar para perguntarÉ o mesmo login gratuito dos cursos.
Nenhuma dúvida por aqui ainda — a primeira pode ser a sua.
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
- Git — git restore — git-scm.com
- Git — git reset — git-scm.com
- Git — git revert — git-scm.com


