Neste post, mostrarei como fazer um git uncommit, isto é, se você fez um git commit
, mas ainda não o enviou para o repositório central, como então desfazer (git undo) o último git commit local sem perder suas alterações ou dados.
Git uncomit ou git undo (desfazer) o último commit
Antes de começarmos, preciso ressaltar que não há um comando uncommit
ou undo
(desfazer) no Git.
Existe um comando git commit
e existem outros comandos para nos ajudar a gerenciar todo o fluxo de trabalho, como os comandos git reset
ou git clean
. Também o comando git revert
que geralmente é mal interpretado.
⚠️ Nota importante: O comando git revert
geralmente é mal compreendido. É crucial reconhecer que esse comando não desfaz um commit (uncommit). Em vez disso, ele cria um novo commit que desfaz as alterações feitas no commit anterior, preservando o histórico de commits.
Dito isso, a necessidade de desfazer - voltar atrás
no Git é real. Por exemplo, quando você erroneamente envia alguns arquivos usando commit convencional ou semântico, mas eles devem ser confirmados em seu próprio contexto.
Git desfazendo o último commit
Desfazer um commit trás certo risco se você não souber como isso funciona. Mas na verdade é muito fácil de fazer se você o entender. Vamos ver algumas maneiras diferentes de desfazer um git commit
.
Vamos trabalhar com o seguinte contexto, você teria algo assim, onde C
é o seu HEAD e (F)
é o estado dos seus arquivos.
(F)
A-B-C
↑
master
git reset hard
Usando git reset --hard
você pode desfazer o commit e remover completamente todas as alterações. Em nosso cenário, o commit C
seria destruído e também descartaria quaisquer alterações de arquivos não confirmadas.
Então executando:
git reset --hard HEAD~
O resultado seria:
(F)
A-B
↑
master
Então, usando git reset --hard HEAD~
agora B
é o HEAD. Devido ao uso de --hard
, os arquivos são redefinidos para seu estado no commit B
.
Recuperando um git reset hard
Se você fez git reset --hard
, mas precisa recuperar o código destruído, ainda há uma maneira de recuperá-lo. Execute este comando:
git reflog
O git reflog
mostrará uma lista de commits (parciais) shas
(isto é, hashes) que você moveu durante o trabalho. Então você pode encontrar o commit que você destruiu e executar:
git checkout -b someNewBranchName shaYouDestroyed
Pronto, você recuperou esse commit.
Isso pode ser feito porque os commits não são realmente destruídos no Git por cerca de 90 dias, então você geralmente pode voltar e resgatar um que você não queria se livrar.
git reset
Usando git reset HEAD~
você pode desfazer commit e unstage (retirar do stage) todos os arquivos.
Em nosso exemplo, se commit C
não foi uma implementação completamente errada, mas apenas precisou de alguns ajustes. Neste cenário, provavelmente você deseja desfazer o commit, mas manter suas alterações para alguma edição antes de fazer um commit melhor.
Então, começando novamente com C
como o HEAD commit:
(F)
A-B-C
↑
master
Para desfazer o commit e retirar arquivos do stage, apenas deixe de fora a opção --hard
:
git reset HEAD~1
Agora o resultado seria:
(F)
A-B-C
↑
master
Observe que em ambos os casos HEAD é apenas um ponteiro para o commit mais recente.
Quando você faz um git reset HEAD~1
, você diz ao Git para mover o ponteiro HEAD para trás um commit. Mas (a menos que você use –hard) você deixa seus arquivos como estavam. Então agora git status mostra as alterações que você verificou em C
. Você não perdeu nenhuma alteração!
git reset soft
Usando git reset --soft HEAD~
você pode desfazer o commit e manter todos os arquivos preparados (em stage).
Este é o toque mais leve, você pode até desfazer seu commit, mas deixa seus arquivos e seu index:
git reset --soft HEAD~1
Isso não apenas deixa seus arquivos em paz, mas também deixa seu índice em paz. Ao fazer git status
, você verá que os mesmos arquivos estão no índice como antes. Na verdade, logo após este comando, você poderia fazer git commit e estaria refazendo o mesmo commit que acabou de desfazer.
Cuidados
Esteja ciente de que essas ações podem não fazer o que você espera se o seu commit errado for uma mesclagem (fast-forward)! Se a sua HEAD estiver em um merge commit (ex: merged branch feature no master),
git reset --hard~1
irá apontar o branch master para o último commit dentro do feature branch. Nesse caso, o commit ID específico deve ser usado em vez do comando relativo.Se o commit foi previamente enviado para o repositório remoto, qualquer operação desfazer causará alguns problemas para o resto dos usuários que têm este commit em sua cópia local, quando eles fizerem um
git pull
no futuro. Portanto, se o commit já foi enviado (pushed), execute isto:git revert <bad-commit-sha1-id> git push origin
Conclusões
Mesmo sem um comando git undo
, o que seria realmente complicado de implementar e usar, o git oferece opções para voltar a realizar alterações com a oportunidade de refazer erros e organizar corretamente seu código-fonte.
Comentários