FNSP Web Page

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 ignorados

O -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 list

Sem 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.

Comentários

Ainda ninguém comentou este artigo.

Voltar ao blog

Gostávamos de saber quantas pessoas visitam o site, com o Google Analytics. Sem a sua autorização não corre nada. Política de Privacidade.