Um passo a passo do tutorial Desfazer um commit: por que o último commit está quebrado, e como git reset --soft permite corrigi-lo sem perder trabalho.
Este cenário começa em um projeto de portfólio onde o último commit está sutilmente quebrado. Você vai ler a história, desfazer esse commit mantendo as mudanças, e commitar novamente do jeito certo. Aqui está o que acontece em cada passo e por quê.
A situação
O projeto tem dois commits. O mais recente, "Add header section", adicionou um header de navegação em index.html. O CSS correspondente para esse header foi escrito em style.css, mas nunca foi preparado: continua na árvore de trabalho como mudança não commitada.
Então o commit está incompleto. O site commitado tem o markup do header apontando para estilos que não foram salvos. Quem fizer checkout desse commit verá um header quebrado.
Comece executando git log --oneline e git status. O log mostra o commit "Add header section"; o status mostra style.css como modificado mas não preparado. Esse desencontro é todo o problema.
A correção, passo a passo
Inspecionar o que foi commitado
git log confirma o último commit, e git status mostra que style.css ainda está modificado na árvore de trabalho. Agora você sabe que o commit capturou index.html mas não style.css.
Desfazer o commit, manter as mudanças
git reset --soft HEAD~1
Isto recua o ponteiro da branch um commit. A mudança em index.html que estava no commit volta para a área de preparação, pronta para ser commitada de novo. Nada nos seus arquivos é apagado.
Preparar tudo desta vez
git add index.html style.css
Agora o markup e seus estilos estão preparados juntos, para que o próximo commit fique completo.
Recommitar a mudança completa
git commit -m "Add header section"
A história tem novamente um único commit "Add header section", mas desta vez inclui style.css. O site está íntegro.
Por que --soft é o modo certo aqui
git reset tem três modos, e a diferença é só em onde suas mudanças vão parar:
--soft recua HEAD e mantém as mudanças preparadas. Ideal aqui, porque você quer recommitar imediatamente.
--mixed (padrão) mantém as mudanças mas não preparadas, na árvore de trabalho.
--hard descarta as mudanças por completo.
Aqui git reset --hard HEAD~1 apagaria o trabalho do header junto com o commit. Reserve --hard para quando você realmente quiser que as mudanças sumam.
Se você executar --hard por acidente, o commit normalmente ainda é recuperável com git reflog, que lista cada posição em que HEAD esteve. O tutorial "Recover Lost Commits" cobre esse fluxo.
Uma ressalva: commits compartilhados
Tudo acima reescreve a história, o que é perfeitamente seguro para um commit que só existe na sua máquina. Quando um commit já foi enviado e baixado por outros, reescrevê-lo força todo mundo a lidar com uma branch divergente. Em uma branch compartilhada, desfaça a mudança com um novo commit:
git revert HEAD