GitMuninnGitMuninn
← Voltar ao blog

Como desfazer um commit no Git: reset, revert e amend

O comando certo para cada situação: corrigir o último commit, desfazer commits locais, reverter algo que já foi para o remoto e recuperar o que parecia perdido.

Commitou o arquivo errado, escreveu a mensagem com erro ou mandou para a main algo que não devia? Todo mundo já passou por isso. O Git tem várias formas de desfazer um commit, e escolher a certa depende de uma pergunta: esse commit já foi enviado para o remoto?

Resumo rápido

  • Corrigir o último commit, ainda não enviado: git commit --amend.
  • Desfazer commits locais, ainda não enviados: git reset.
  • Desfazer um commit que já está no remoto: git revert.
  • Recuperar algo que parecia perdido: git reflog.

Corrigir o último commit com amend

Se o problema é só a mensagem, ou se você esqueceu de incluir um arquivo, o --amend substitui o último commit por uma versão corrigida:

# só trocar a mensagem
git commit --amend -m "Corrige validação do e-mail"

# incluir um arquivo esquecido, mantendo a mensagem
git add src/validacao.ts
git commit --amend --no-edit

O --amend cria um commit novo no lugar do antigo. Por isso, use só em commits que ainda não foram enviados. Se já enviou, você vai precisar de git push --force-with-lease, e isso atrapalha quem já baixou o commit antigo.

Desfazer commits locais com reset

O git reset move o branch para um commit anterior. A diferença entre os modos é o que acontece com as mudanças dos commits desfeitos:

git reset --soft HEAD~1   # desfaz o commit e deixa as mudanças no stage
git reset --mixed HEAD~1  # desfaz o commit e deixa as mudanças fora do stage (padrão)
git reset --hard HEAD~1   # desfaz o commit e apaga as mudanças
  • --soft é útil para juntar vários commits em um: desfaça os últimos e commite de novo.
  • --mixed é útil para refazer o commit escolhendo melhor os arquivos.
  • --hard descarta o trabalho. Use com cuidado e só quando tiver certeza.

HEAD~1 significa um commit antes do atual. HEAD~3 volta três commits. Você também pode usar o hash: git reset --soft a1b2c3d.

Desfazer um commit já enviado com revert

Quando o commit já está no remoto e outras pessoas podem ter baixado, não reescreva o histórico. Use o git revert, que cria um commit novo fazendo exatamente o contrário:

git revert a1b2c3d
git push

O histórico continua mostrando o commit original e, depois dele, o commit que o desfez. Ninguém do time precisa fazer nada especial.

Para reverter um commit de merge, diga ao Git qual lado manter com -m 1, que normalmente é o branch principal:

git revert -m 1 <hash-do-merge>

Recuperar o que parecia perdido com reflog

Fez um reset --hard e se arrependeu? O Git guarda por um tempo todas as posições por onde o HEAD passou. O git reflog mostra essa lista:

git reflog
# a1b2c3d HEAD@{0}: reset: moving to HEAD~1
# f4e5d6c HEAD@{1}: commit: Adiciona exportação em CSV

git reset --hard f4e5d6c

Isso funciona para commits que existiram no seu repositório local. Mudanças que nunca foram commitadas e foram apagadas com --hard não aparecem no reflog.

Desfazer mudanças que ainda não viraram commit

  • Descartar mudanças em um arquivo: git restore src/app.ts.
  • Tirar um arquivo do stage sem perder a mudança: git restore --staged src/app.ts.
  • Guardar tudo para depois: git stash, e recuperar com git stash pop.

Desfazendo commits no GitMuninn

No GitMuninn, o grafo mostra exatamente onde cada commit está e em quais branches ele já entrou. Você vê se o commit já foi para o remoto antes de decidir entre reset e revert, e o histórico de cada arquivo fica a um clique.

Veja seus branches no GitMuninn.

Entre na lista de lançamento e ganhe um cupom de 50% de desconto por 12 meses.

Plano de interesse

Para macOS, Windows e Linux. Sem spam, saia quando quiser.