Olá senhores e senhoras! =]
Em meu primeiro post no Buteco vou demonstrar como recuperar dados perdidos do git-stash. Talvez salvando muitas horas de trabalho que poderiam ser perdidas acidentalmente. Na realidade o método demonstrado neste artigo pode ser utilizado para recuperar qualquer objeto git perdido. Antes de mais nada, enquanto você estiver implementando alguma grande feature, quebre-a em pequenos pedaços e faça commits regularmente. Não é uma boa ideia permanecer muito tempo sem “comitar”. Tenha cuidado.
Vamos simular o cenário para mostrar o que você pode fazer quando perder dados do stash do git. Em um repositório para demonstração existe apenas um arquivo, main.c
. Ele será utilizado para demonstrar o problema e a solução. Então, nosso repositório está assim agora:
e existe apenas um commit:
A primeira versão do arquivo é:
Vamos começar a codificar alguma coisa. Para este exemplo, não é necessário uma grande mudança, é apenas alguma coisa para colocar no git stash. Para isso, será adicionado apenas uma nova linha. O git-diff após a alteração é:
Agora, suponha que você tenha que realizar o pull de novas alterações de um repositório remoto e não quer realizar o commit de suas alterações por que elas não estão terminadas. Assim, você decide joga-las para o stash, baixar as alterações do repositório remoto e aplicar seu código novamente. Por isso, você executa o seguinte comando para mover suas alterações para o git stash:
git stash
Analisando o stash será possível ver que o comando funcionou como o esperado:
Neste momento, o código está em um local seguro e o branch master está limpo e o pull das mudanças pode ser realizado. Depois de ter atualizado o branch local com as alterações do branch remoto, é a hora de aplicar o código no master novamente. Vamos supor que acidentalmente você executa:
git stash drop
e depois é possível verifica, com o comando git stash list
, que o stash limpou, e que o código foi removido e não foi aplicado no branch master. OMG! Quem poderá nos ajudar? Como você irá ver em breve, o git não apagou o objeto que contem as alterações. Ele apenas removeu a referência para ele. Para provar isso, pode ser usado o git-fsck. Este comando, verifica a conectividade e validade dos objeto na base de dados. Veja que no começo do nosso repositório foi executado o comando git-fsck e a saída foi:
Basicamente, git-fsck mostrou os objetos que são inalcançáveis ( flag –unreachable
). Como pode ser visto, ele não mostrou nenhum objeto. Depois que os elementos do stash foram dropados o git-fsck mostrou:
Na última execução pode ser visto que existem três objeto inalcançáveis. Mas qual deles é o código perdido? Temos que procurar por ele, para isso podemos usar o comando git-show para visualizar o que é cada objeto.
Ai está! O ID 95ccbd927ad4cd413ee2a28014c81454f4ede82c é a alteração que estávamos procurando e temos que recuperá-lo! Uma possível solução é fazer o checkout do ID em um novo branch ou aplicar o commit diretamente. Neste exemplo será utilizado o git-stash para aplicar o commit no branch master novamente.
git stash apply 95ccbd927ad4cd413ee2a28014c81454f4ede82c
É importante relembrar, git executa seu garbage collector (gc) periodicamente. Após a execução do gc não será mais possível ver os objetos inalcançáveis.
Referência