Voltar ao blog

Como desfazer o último commit no Git com segurança

3 de setembro de 2026

TL;DR: para desfazer o último commit mantendo as mudanças, rode git reset --soft HEAD~1 (as mudanças ficam no stage) ou git reset HEAD~1 (as mudanças ficam na sua working tree). Se o commit já foi enviado, rode git revert HEAD — ele cria um commit novo que desfaz o anterior sem reescrever o histórico. Esses três comandos cobrem quase todo momento de “commitei cedo demais”. O resto do guia passa caso por caso com comandos prontos para colar, explica a diferença entre --soft, --mixed e --hard e mostra como recuperar a situação se algo der errado. Todo comando abaixo funciona em qualquer instalação recente do Git no Linux, macOS ou Windows.

Como desfazer o último commit e manter as mudanças?

A situação mais comum: você commitou, percebeu um typo, um arquivo faltando, ou lembrou que a mudança pertencia a outro commit. Nada foi enviado. Desfaça o commit e devolva tudo ao lugar:

# O commit sai do histórico — as mudanças voltam para a área de staging
git reset --soft HEAD~1

# As mudanças voltam para a working tree (fora do stage)
git reset HEAD~1

HEAD~1 significa “um commit antes de onde o HEAD aponta agora”. Depois de qualquer um dos comandos, seus arquivos continuam intactos no disco — só o ponteiro da branch se moveu. Confirme com git status: com --soft as mudanças estão no stage, prontas para commitar de novo com as correções embutidas; sem flag elas estão fora do stage, e você pode editar à vontade antes.

Um hábito mais seguro, quando você só quer adicionar arquivos ao último commit, é não desfazê-lo:

git add forgotten-file.txt
git commit --amend --no-edit

O --amend substitui o último commit no lugar (aqui, sem mudar a mensagem). Lembre que amendar um commit já enviado reescreve o histórico — volto nisso abaixo.

Qual é a diferença entre —soft, —mixed e —hard?

Essa é a parte que vale decorar, porque a flag decide para onde suas mudanças vão — e se elas podem se perder:

FlagDesfaz o commit?Mudanças no discoMudanças no stage?Uso típico
--softSimMantidasSimCommitar de novo com ajustes pequenos
--mixed (padrão)SimMantidasNãoReagrupar mudanças, re-stage seletivo
--hardSimApagadasJogar o trabalho fora por completo
git revertNão (commit novo)MantidasDesfazer um commit já enviado

O --hard é o único perigoso: ele descarta o commit e as mudanças. Antes de qualquer reset --hard, guarde o que você tem num stash ou numa branch:

git branch backup-before-reset   # seguro barato
git reset --hard HEAD~1          # commit + mudanças apagados

Se você já rodou a versão perigosa, nem tudo está perdido — o git reflog lembra por onde o HEAD passou:

git reflog                       # ache o hash do commit que você perdeu
git reset --hard HEAD@{1}        # ou: git reset --hard <hash>

O reflog guarda commits órfãos por cerca de 90 dias por padrão, então “dei hard-reset sem querer” é quase sempre recuperável se você agir antes do garbage collection.

E se eu já tiver enviado o commit?

Se o commit está numa branch compartilhada (qualquer uma que não seja a sua feature branch), não reescreva o histórico. Use git revert, que calcula a mudança oposta e a commita:

git revert HEAD
git push

Todo mundo que puxar simplesmente recebe um commit novo que remove as mudanças do antigo. Sem force-push, sem colegas quebrados. Para desfazer uma sequência de commits, reverta um intervalo: git revert --no-commit HEAD~3..HEAD && git commit.

A alternativa — git reset --hard HEAD~1 && git push --force-with-lease — só é aceitável numa branch em que ninguém mais constrói, e o --force-with-lease (nunca o --force puro) é a única forma segura, porque recusa a operação se alguém fez push nesse meio-tempo. Force-push em branch compartilhada é assim que times perdem commits e os logs de CI misteriosamente param de bater com o checkout de qualquer um.

Como desfazer o commit mas guardá-lo para depois?

Às vezes o commit é um bom trabalho no endereço errado — na branch errada, ou cedo demais. Em vez de desfazer, mova:

git branch stash-commit          # estacione o commit numa branch nova
git reset --hard HEAD~1          # depois limpe a branch atual

Ou leve só o commit para outra branch sem tocar na atual:

git cherry-pick <hash>           # estando na branch de destino

Entre reset --soft, cherry-pick e revert, não existe commit que você não consiga realocar ou anular — o truque é escolher “mover” ou “desfazer” antes de correr para uma flag.

Qual undo usar? Um guia rápido de decisão

  1. Não enviado, quer corrigir e commitar de novogit reset --soft HEAD~1
  2. Não enviado, quer remontar o stage seletivamentegit reset HEAD~1 (mixed)
  3. Quer as mudanças fora completamentegit reset --hard HEAD~1 (o reflog sabe, se você se arrepender)
  4. Já enviado para uma branch compartilhadagit revert HEAD
  5. O commit pertence a outra branchcherry-pick, não desfaça

Uma última dica operacional: se um commit ruim chegou a um servidor — um hook de deploy que falhou, um runner de CI se comportando mal depois de um force-push — o próximo lugar para olhar são os logs da máquina, não o Git. Em qualquer box com systemd, journalctl -u <service> -n 100 mostra exatamente o que rodou e quando; nosso cheat sheet de journalctl tem os padrões prontos para colar. E se o seu fluxo inclui LLM local para revisar diffs, comparamos as duas opções principais em Ollama vs LM Studio.

— mrsaynothing

Get the next one by email

One email per post. No spam, no algorithms.

self-hosted · no third parties · one-click unsubscribe

what is this?

journalctl: cheat sheet para ver e filtrar logs do Linux

Gostou dos artigos? É assim que eu construo profissionalmente. me contrate