segunda-feira, 5 de fevereiro de 2018

Removendo commits indesejáveis do repositório git sem precisar do revert



Hoje vamos ver como deletar aquele commit que você não gostou e quer se livrar dele de uma só vez. Isso tudo sem precisar de utilizar do comando revert, para reverter o estrago que fez.

OBS: Este blog não se responsabiliza por estragos causados por quem seguir as dicas a seguir. Se não quer ter problemas no seu repositório ou no repositório dos outros, FAÇA UM BACKUP PRIMEIRO. Seja dando um clone em outro lugar, copiando a pasta .git para um outro lugar ou dando um tar/zip no seu repositório. Depois não venha chorando dizendo que fez besteira.

Vamos começar pelo mais simples. Você quer, simplesmente, remover o último commit ao invés de utilizar o revert. Esse comando é bem fácil é só fazer.

git reset --hard HEAD~1

Aí o repositório volta ao estado de como era antes do commit.

Agora vamos a situação do commit, bem no meio, que está dando problemas. A situação normal é rodar um revert para corrigir. Mas você quer se livrar do código indesejável. Neste caso existe uma maneira.

Vamos ver um exemplo de git log:

Number Hash     Commit Message               Author

1      2c6a45b  (HEAD) Adicionando novidades Desenv.
2      ae45fab  Melhorando banco de dados    Estagiário 1
3      77b9b82  Corrigindo banco de dados    Estagiário 2
4      3c9093c  Dando merge com master       Desenv.
5      b3d92c5  Adicionando novo evento      Colega
6      7feddbb  Adicionando arquivos         Desenv.
7      a809379  Commit inicial               Desenv.


Mas você vê que os estagiários complicaram na parte do banco de dados e quer se livrar deste código, de uma vez por todas, sem passar por revert. É só seguir a numeração. Escolha o primeiro a deletar e o primeiro a manter, de baixo para cima. Neste caso o primeiro a remover é o 3 e o primeiro para manter é o 1. Assim o comando para rodar é o:

git rebase --onto HEAD~3 HEAD~1 master

Depois disso os commits desaparecem do seu repositório.

Mas e se os códigos para remover estão espalhados? Neste caso, faça um intervalo de cada vez. Se tentar com o primeiro código para remover e o primeiro a manter, depois de várias sequencias, vai remover aquilo que não quer que remova e vai ter que precisar do backup que pedi para fazer no início. Lembra?

Atualização (1 ano depois): E se não der certo: https://www.adilson.net.br/2019/02/usando-rebase-para-unificar-as.html

Outra opção, neste estilo, é com o cherry-pick. Mas ainda não testei, mas pode dar uma olhada melhor nos links abaixo.

Mais informações sobre isso em:

https://www.clock.co.uk/insight/deleting-a-git-commit
https://www.git-tower.com/learn/git/faq/undo-last-commit

Tenham uma boa semana.