Git cherry-pick ao resgate

Eu li em algum lugar que só se você estiver muito determinado a deletar algo de um repositório Git para conseguir, e ainda assim você vai sofrer bastante. Ainda bem, por que hoje eu quase destruo um projeto.

Em momentos de muita inspiração eu saio programando como se não houvesse amanhã e nesse rampage eu acabo esquecendo de fazer commits. Para evitar aqueles commits enormes, que modificam o sistema inteiro, eu prefiro selecionar manualmente as modificações, fazendo agrupamentos lógicos e commitando um por um. Para isso, eu uso o app do Github. Com ele, consigo selecionar os arquivos, visualizar as alterações e até mesmo selecionar as linhas individuais. É bem útil.

Screen Shot 2015-11-25 at 2.46.42 AM

E num desses dias, eu estava selecionando os arquivos e, por algum motivo, o botão de Undo ficou com o foco (como na imagem). Acontece que algumas vezes quando você seleciona outra janela, o foco continua no botão. Significa que quando eu fui de volta pro meu editor e comecei a apertar Enter, eu estava de fato pressionando o botão de undo. Ótimo. Eu devo ter apertado o Enter umas vinte vezes antes de me tocar que não era o meu computador travado e sim o foco em outra janela, já acontecera outras vezes. E quando voltei no Github lá estavam todos os meus commits desfeitos.

Na hora bateu um desespero, pensei que tinha perdido dias de trabalho. Mas lembrei que tem que ser MUITO incompetente pra perder algo no Git. E foi assim que descobri o cherry-pick. Explico. O botão de Undo do Github nada mais faz do que executar um git reset --soft HEAD~. Isso desfaz o último commit, mas mantém as modificações nos arquivos. Mas agora, com vinte commits, vários arquivos para serem analizados eu não queria ter que olhar arquivo por arquivo para achar as modificações, agrupar e recommitar tudo.

Aí entra o cherry-pick. O git cherry-pick permite que você selecione um commit qualquer e aplique como um novo commit no HEAD. Com isso, bastava eu encontrar de alguma forma os hashes dos vinte commits desfeitos. Como? Se você for mais esperto que eu, mantém o seu repositório sempre sincronizado com o origin. Nesse caso, bastava ir no origin e pegar os hashes dos commits. Como eu não tinha sincronizado a branch que estava trabalhando, não tinha esse luxo. A alternativa é tão simples quanto: git reflog. O git reflog mantém um registro das referências mais recentes. Então bastava eu encontrar as referências de commits e pegar o hash. Depois, foi questão de executar git cherry-pick commit-hash vinte vezes e pronto: meu trabalho estava a salvo.

Só sendo muito, mas muito incompetente pra conseguir perder algo no Git.