git stash: onde o trabalho vai, e de onde às vezes não volta
O git stash é uma pilha, não um ramo. Guarda o que está alterado, devolve a árvore ao estado do último commit, e fica à espera. É cómodo, e é o comando com que mais trabalho se perde — por três razões que não são óbvias.
1. Os ficheiros novos não vão lá dentro
Esta é a que custa trabalho a sério. O git stash guarda o que o Git já segue. Um ficheiro criado agora, que nunca foi adicionado, fica onde está — e quem guardou tudo convencido de que a árvore está limpa, e a seguir corre um git clean -fd, acabou de o apagar sem rede.
git stash # so o que o Git ja segue
git stash -u # inclui os ficheiros novos
git stash -a # inclui tambem os ignoradosO -u devia ser o hábito. O -a quase nunca, porque arrasta node_modules e companhia.
2. pop e apply não são a mesma coisa
O pop aplica e tira da pilha. O apply aplica e deixa lá. Quando não há certeza de que vai entrar sem conflito, apply é a escolha prudente: se correr mal, a entrada continua a existir.
E um pormenor que tranquiliza: em caso de conflito, o pop não descarta a entrada. Fica na pilha até o conflito ser resolvido — o que significa que um pop que deu errado não perdeu nada, ao contrário do que parece no meio da confusão.
3. A pilha não pertence ao ramo
Guarda-se no ramo A, muda-se para B, faz-se pop: aplica em B. O Git não se opõe, porque a pilha é do repositório e não do ramo.
Às vezes é precisamente o que se quer — é a forma mais curta de mover trabalho começado no ramo errado. Noutras é como se descobre, meia hora depois, que as alterações do redesign foram aplicadas por cima de uma correção urgente.
4. Pôr-lhe um nome
git stash push -m "formulario a meio, falta validar"
git stash listSem mensagem, a listagem diz WIP on main: a1b2c3d, que daqui a uma semana não identifica nada. Com três entradas guardadas e nenhuma descrita, a única forma de saber o que está em cada uma é aplicá-las para ver — e aí já se está a mexer na árvore para responder a uma pergunta de arquivo.
5. Quando se perde, ainda lá está
Uma entrada guardada é um commit como os outros, só que sem ramo a apontar para ele. Um drop a mais não apaga nada de imediato: desaparece a referência, e o commit fica órfão até a recolha de lixo passar.
git fsck --unreachable | grep commit
git show <hash>
git stash apply <hash>Vale a pena saber isto antes de precisar. É a mesma família de recuperações do artigo do restore, reset e revert: no Git, quase nada desaparece de verdade no mesmo dia.
6. Quando não usar
A regra que eu uso: o stash é para minutos, não para dias.
Tudo o que tiver de sobreviver mais do que uma tarde merece um commit num ramo. Um commit tem mensagem, tem data, aparece no histórico, pode ir para o servidor, e sobrevive a um clone novo. Uma entrada na pilha não tem nada disso: é invisível para a equipa e, daqui a três semanas, para quem a guardou. E arrumar os commits depois é trivial, como no artigo do rebase interativo.
O resumo
Usar -u, porque os ficheiros novos não vão. Preferir apply quando há dúvida. Pôr mensagem, sempre. Saber que a pilha é do repositório e não do ramo. E, para qualquer coisa que dure mais do que uma pausa para café, um ramo em vez da pilha.