O seguinte aconteceu algumas vezes e estou procurando uma maneira automatizada de me pegar antes de repetir o erro. Soluções dizendo "apenas lembre-se" ou "simplesmente não faça isso" não serão marcadas como corretas.
Muitas vezes, estarei trabalhando em um branch do git, tenho algum código não confirmado e preciso fazer uma alteração rapidamente em outro branch. Eu costumo git stash
esconder o código não confirmado, git checkout
para trocar para o outro branch, faço e comprometo minhas alterações, então git checkout
para o outro branch. E espero que eu me lembre de git stash pop
. O problema é que nem sempre me lembro, especialmente se acabo tendo que fazer algumas alterações no outro branch que acabam levando algumas horas/dias.
Existe um hook git que eu possa escrever que, quando eu fizer checkout de um branch que tem um stash nele, ele me enviará uma pequena mensagem? Algo como:
$ git checkout foo
Switched to branch 'foo'
You have 1 stash on this branch, use `git stash pop` to unstash it.
Não precisa ser chique, mas acho que vai me poupar muita dor de cabeça. Respostas como "apenas lembre-se de correr git stash list
" não serão aceitas.
Solução sugerida: confirmações temporárias.
Como exemplo, vamos pegar um cenário típico:
Essa é realmente uma situação muito comum. Mas então você faz:
Vamos mudar de curso neste ponto. Use stash apenas para snippets que você deseja excluir, mas pode precisar inspecionar mais tarde em caso de uma reflexão tardia.
Para código válido, mas inacabado, não faça stash, mas commit em vez disso. Use para isso alguns aliases rápidos:
Você tem que mudar de branch com pressa?
git wip
e fazer checkout em outro lugar. Quando você mudar de volta para seu branch, desfaça o commit temporário com seugit unwip
e retome o trabalho.Você se acostumará muito rápido, e o estoque permanecerá (como deveria ter sido chamado) uma lixeira de papel. (Que, como a do Windows, não apaga as coisas imediatamente, mas permite que você inspecione e restaure arquivos apagados recentemente, de vez em quando, se necessário)
Como os branches podem compartilhar os mesmos commits em seus históricos, é difícil dizer se um stash está relacionado a um branch específico. Podemos usar o hook post-checkout para lembrá-lo das possíveis entradas do stash que você pode esquecer.
Depois que trocamos/fazemos checkout de um branch,
post-checkout
é invocado. Ele recebe 3 parâmetros: o head anterior, o head atual e um sinalizador indicando se foi um checkout de branch ou um checkout de arquivo. Podemos testar algumas ou todas as entradas stash. Se o head atual for o primeiro pai de uma entrada stash, dizemos que o stash está neste branch.Aqui estão alguns problemas conhecidos que posso pensar. Há palavras como
WIP on master
ouWIP on dev
na descrição padrão do stash, mas não as usamos no hook. Vários branches podem se referir ao mesmo commit e um stash feito em um deles pode ser aplicado a outro head. Às vezes, podemos trabalhar em um HEAD destacado que não tem nome de branch e também pode aceitar uma aplicação de stash. O hook apenas imprime as mensagens de lembrete o máximo possível, o que pode ser barulhento.Outro problema é que se você não mantiver bem as entradas do stash, a lista de entradas do stash ficará longa, e o hook pode levar um bom tempo. Você pode testar apenas as N entradas principais no loop while.
O hook não pode reportar tal stash. Crie um stash A em
main
, crie um novo commit e então faça outro stash B, troque paramain
para invocar o hook. Como o pai de A não é o head atual, ele não é reportado. Um caso mais complicado é quemain
tem um número de heads divergentes e stashes são feitos neles. Apenas os stashes relacionados com o head atual são reportados. É comum quando você faz alguns experimentos no branch local e reinicia entre esses heads de teste. Se você também estiver interessado nessas entradas de stash, o teste no loop while precisa de mais códigos.