Existem algumas maneiras diferentes de desfazer as coisas no git, mas para o propósito deste post vamos considerar o seguinte cenário:
- um repositório com cópias locais e remotas
- vários colaboradores
- um commit recente que já foi adicionado ao repositório remoto (“merged”, pra usar o termo “git” em inglês) mas que precisa ser revertido
git revert pra resolver esse problema! ✨
RESUMÃO: passos pra reverter um commit em um repositório remoto:
- atualize a cópia local do repostitório na seu branch principal: git pull
- crie um novo branch: git checkout -b remove_codigo_bugado
- encontre o hash do commit com bugs com git log
- git revert <hash_do_commit_que_vai_ser_desfeito> [-m 1 –no-edit]
O comando acima criará um novo commit onde todas as alterações do commit original que foi adicionado ao repositório remoto serão revertidas. Isso é bom porque fazendo desse jeito você mantém o histórico do repositório inalterado.
As opções opcionais mostradas no comando acima significam:
-m n : se você está revertendo um “merge” commit (o commit final que foi adicionado ao repositório remoto), você precisa passar esta opção com um número ( tem uma entrada em inglês no StackOverflow explicando o porquê )
–no-edit : (note que são dois traços no início da opção!) isso vai evitar que o editor de texto padrão abra automaticamente
EXEMPLO passo-a-passo:
Meu branch principal e local chamado main
tá assim:
└❯ git log
commit 9ebef49af9f50996f32c863604b1fc6fdce71e26 (HEAD -> main, origin/main, origin/HEAD)
Author: Flavia Bastos <meu_email>
Date: Tue Oct 4 19:22:55 2022 -0300
Corrigir ortografia
Nesse meio tempo alguém adiciona um commit novo no repositório remoto. Quando eu puxo as alterações novas pro meu repositório local, eu vejo o commit novo ( 86d1c24f17aa7
) e um merge commit novo ( 5aa51c6ea265cc
) para essas alterações:
└❯ git log
commit 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df (HEAD -> main, origin/main, origin/HEAD)
Merge: 9ebef49 86d1c24
Author: Outra pessoa <outro_email>
Date: Thu Oct 6 17:14:15 2022 -0400
Merge pull request #1 from Outra pessoa/caso_123
Codigo novo cheio de firula
commit 86d1c24f17aa7fd264a26d81533e53f6f48dea24 (origin/caso_123, caso_123)
Author: Outra pessoa <outro_email>
Date: Thu Oct 6 18:08:49 2022 -0300
Codigo novo cheio de firula
commit 9ebef49af9f50996f32c863604b1fc6fdce71e26
Author: Flavia Bastos <meu_email>
Date: Tue Oct 4 19:22:55 2022 -0300
Corrigir ortografia
Observe aqui que o merge commit ( 5aa51c6ea265cc
) também descreve os commits antecedentes no atributo “Merge”:
Merge: 9ebef49 86d1c24
Daí acontece que esse código sofisticado também estava com bugs e fez com que algumas coisas quebrassem feio. Quem nunca, neah? ?
Vamos corrigir isso rapidamente criando um branch novo a partir da última atualização da branch principal (main
):
└❯ git checkout -b corrige_bug
Switched to a new branch 'corrige_bug'
A partir da mensagem do comando git log
acima, sabemos que queremos o hash do commit mais recente (o primeiro da lista nesse caso), mas pode haver outros commits novos depois dele. Sempre confirme rodando o git log
de novo.
Agora vamos reverter o commit com bug ( 5aa51c6ea265cc
) – observe que estamos em um branch separado e estou usando a opção -m 1
, porque quero reverter para seu primeiro antecedente 9ebef49
(se eu usasse -m 2 ao invés, ele reverteria para o segundo antecedente 86d1c24
):
└❯ git revert 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df -m 1 --no-edit
[corrige_bug 560ad2d] Revert "Merge pull request #1 from Outra pessoa/caso_123"
Date: Thu Oct 6 18:30:50 2022 -0300
1 file changed, 1 insertion(+), 1 deletion(-)
O úlimo passo agora é mandar esse branch corrige_bug
pro repositório remoto e dar merge na alteração:
└❯ git push origin corrige_bug
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 402 bytes | 402.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote:
remote: Create a pull request for 'corrige_bug' on GitHub by visiting:
remote: https://github.com/FlaviaBastos/meu_projeto/pull/new/corrige_bug
remote:
To github.com:FlaviaBastos/meu_projeto.git
* [new branch] corrige_bug -> corrige_bug
Depois que essa última alteração for adicionada ao repositório remoto, volte para o branch principal main
no seu repositório local, puxe as últimas alterações e confirme com o git log
que o commit com erros foi revertido:
❯ git log
commit 4332e3e999c2056019cf64255f17b32a6ef1992b (HEAD -> main, origin/main, origin/HEAD)
Merge: 5aa51c6 560ad2d
Author: Outra pessoa <outro_email>
Date: Thu Oct 6 17:53:28 2022 -0400
Merge pull request #2 from FlaviaBastos/corrige_bug
Revert "Merge pull request #1 from Outra pessoa/caso_123"
commit 560ad2ddfd207fad2f609873270bdd3f645bb4b6 (origin/corrige_bug, corrige_bug)
Author: Flavia Bastos <my_email>
Date: Thu Oct 6 18:30:50 2022 -0300
Revert "Merge pull request #1 from Outra pessoa/caso_123"
This reverts commit 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df, reversing
changes made to 9ebef49af9f50996f32c863604b1fc6fdce71e26.
commit 5aa51c6ea265cc43b93a66de97ca4d8fcafc69df (HEAD -> main, origin/main, origin/HEAD)
Merge: 9ebef49 86d1c24
Author: Outra pessoa <outro_email>
Date: Thu Oct 6 17:14:15 2022 -0400
Merge pull request #1 from Outra pessoa/caso_123
Codigo novo cheio de firula
Ufa! Tudo resolvido! ?
MAS peraí, o RESET --HARD
faz a mesma coisa, não?
Sim. Porém, apenas localmente. O comando git reset
vai mover o ponteiro do seu repositório para qualquer commit que você definir, efetivamente removendo qualquer coisa depois dele. Se você rodar um git status
, você não verá mais esses outros commits, nem nada de novo que precise ser feito commit e você estará reescrevendo o histórico do repositório desse jeito. Isso só é seguro se você estiver trabalhando sozinho ou em um branch que ainda não foi mandado e anexado ao repositório remoto.
Se você precisar enviar as alterações de reversão de commit para um repositório remoto, você deve usar o git revert
.
Pra saber mais:
Documentação do git revert: https://git-scm.com/docs/git-revert/pt_BR
Compartilhe esse artigo!
O artigo Como reverter um commit no git foi publicado originalmente no flaviabastos.ca