Desfazendo Alterações no Git: Reset, Restore, Revert Explicados
Entenda git restore, reset e revert para que você possa desfazer arquivos do stage, descartar edições locais, desfazer commits e evitar reescrever histórico compartilhado.
Desfazendo Alterações no Git: Reset, Restore, Revert Explicados
Desfazer alterações no Git é seguro quando você sabe qual camada está alterando: a árvore de trabalho, a área de staging ou o histórico de commits. Os comandos comuns são git restore, git reset e git revert, e eles resolvem problemas diferentes.
A grande regra é simples: use restore para arquivos, reset para alterações no histórico local e revert para desfazer commits que outras pessoas já podem ter.
Entendendo os Conceitos Principais
Mantenha essas áreas claras:
- Árvore de trabalho: os arquivos que você edita.
- Área de staging, também chamada de índice: as alterações selecionadas para o próximo commit.
- Histórico de commits: os commits já registrados.
HEAD: o commit atual para o qual seu branch aponta.
Execute git status antes de desfazer qualquer coisa. Ele informa se as alterações estão não preparadas (unstaged), preparadas (staged) ou já commitadas.
git restore: Para Descartar Alterações no Diretório de Trabalho e na Área de Staging
Use git restore quando quiser alterar arquivos na árvore de trabalho ou na área de staging sem mover o histórico do branch.
Desfazendo Arquivos do Stage
Se você preparou um arquivo por engano, remova-o do stage com --staged:
git restore --staged <arquivo>
Para remover tudo do stage:
git restore --staged .
Suas edições no arquivo permanecem na árvore de trabalho. Elas são simplesmente removidas do próximo commit.
Descartando Alterações no Diretório de Trabalho
Para descartar edições não preparadas em um arquivo:
git restore <arquivo>
Isso faz a cópia da árvore de trabalho corresponder ao índice. Se o arquivo não estiver preparado, isso geralmente significa que ele volta para HEAD. Revise git diff primeiro, pois isso descarta edições locais.
Para descartar alterações preparadas e não preparadas de um arquivo e restaurá-lo de HEAD:
git restore --source=HEAD --staged --worktree <arquivo>
Restaurando um Arquivo de um Commit Específico
Você também pode trazer de volta um arquivo de um commit mais antigo:
git restore --source=<commit> -- caminho/para/arquivo
Isso altera o arquivo em sua árvore de trabalho. Faça commit se a versão antiga for o que você deseja daqui para frente.
git reset: Reescrevendo o Histórico
Use git reset quando quiser mover o ponteiro do branch atual. Ele também pode alterar a área de staging e a árvore de trabalho, dependendo do modo.
Entendendo os Modos (--soft, --mixed, --hard)
Os três modos comuns são:
git reset --soft HEAD^
Move HEAD um commit para trás e mantém as alterações do commit desfeito preparadas (staged).
git reset --mixed HEAD^
Move HEAD um commit para trás e mantém as alterações do commit desfeito não preparadas (unstaged). --mixed é o padrão, então git reset HEAD^ faz o mesmo.
git reset --hard HEAD^
Move HEAD um commit para trás e descarta as alterações correspondentes da área de staging e da árvore de trabalho. Isso é destrutivo. Não execute casualmente.
Padrões úteis de reset:
git reset --soft HEAD^ # refaça o último commit local, mantenha alterações preparadas
git reset HEAD^ # desfaça o último commit local, mantenha alterações não preparadas
git reset # remova todas as alterações preparadas do stage
git reset --hard origin/main # descarte alterações locais e corresponda a origin/main
Resetando um Commit Antigo
Para mover seu branch dois commits para trás enquanto mantém as alterações em sua árvore de trabalho:
git reset --mixed HEAD~2
Apenas redefina commits que são locais ou que sua equipe concordou em reescrever. Se os commits já estão em um branch compartilhado, prefira git revert.
git revert: Criando um Novo Commit para Desfazer Alterações
git revert cria um novo commit que aplica o inverso de um commit anterior. Ele não exclui ou move o commit original, portanto é seguro para branches compartilhados.
Reverter um commit:
git revert <hash-do-commit>
Reverter um intervalo:
git revert HEAD~3..HEAD
Se conflitos aparecerem, resolva-os, prepare os arquivos e continue:
git add <arquivos-corrigidos>
git revert --continue
Reverter um commit de merge requer cuidado extra porque o Git precisa saber qual pai deve ser tratado como a linha principal:
git revert -m 1 <commit-de-merge>
Faça isso apenas quando você entender o que o merge introduziu. Para branches de produção, peça uma revisão antes de reverter merges.
Escolhendo o Comando Correto
Use este guia rápido:
- Remover um arquivo do stage:
git restore --staged <arquivo>. - Descartar edições não preparadas em um arquivo:
git restore <arquivo>. - Desfazer o último commit local e manter alterações preparadas:
git reset --soft HEAD^. - Desfazer o último commit local e manter alterações não preparadas:
git reset HEAD^. - Descartar alterações e commits locais destrutivamente:
git reset --hard <commit>. - Desfazer um commit enviado com segurança:
git revert <hash-do-commit>.
Conclusão Prática
Antes de desfazer qualquer coisa, execute git status e decida o que você está alterando. Use restore para limpeza em nível de arquivo, reset para commits locais não enviados e revert para histórico compartilhado. Quando um comando incluir --hard, pause e verifique git diff primeiro.