Do livro do Git SCM :
Freqüentemente, quando você trabalha em parte de seu projeto, as coisas estão em um estado confuso e você deseja alternar entre ramificações um pouco para trabalhar em outra coisa. O problema é que você não deseja confirmar o trabalho pela metade apenas para voltar a esse ponto mais tarde. A resposta para esse problema é o comando git stash.
O armazenamento em cache leva o estado sujo do seu diretório de trabalho - ou seja, os arquivos rastreados modificados e as alterações faseadas - e o salva em uma pilha de alterações inacabadas que você pode aplicar novamente a qualquer momento.
Dada esta descrição, eu diria que este é um anti-padrão. Uma explicação excessivamente simplificada do Git Stash seria que ele é o "Recortar e colar" do controle de origem. Você pega vários arquivos alterados, "os esconde" em uma caneta de exploração fora do fluxo de trabalho normal de ramificação do Git e depois reaplica essas alterações em um ramo diferente posteriormente.
Voltando um pouco mais longe, comprometer-se a dominar é o anti-padrão aqui. Use ramos. Foi para isso que eles foram projetados.
Realmente se resume a isso:
Você pode martelar um parafuso na parede e ele exibirá uma foto, mas usar uma chave de fenda é o que você deve fazer. Não use um martelo quando a chave de fenda estiver bem ao seu lado.
Sobre como confirmar o código "quebrado"
Enquanto o seguinte é opinião, cheguei a essa opinião por experiência própria.
Comprometa cedo e comprometa-se frequentemente. Confirme o código quebrado que desejar. Veja o seu histórico de consolidação local como "economize pontos" enquanto você se esquiva de algo. Depois de concluir um trabalho lógico, faça um commit. Claro que isso pode quebrar tudo, mas isso não importa, desde que você não force esses commits. Antes de empurrar, rebase e esmague seus commits.
- Criar nova ramificação
- Hack hack hack
- Confirmar código quebrado
- Polir o código e fazê-lo funcionar
- Confirmar código de trabalho
- Rebase e Squash
- Teste
- Empurre quando os testes estiverem passando
Para o OP, esse encadeamento de mensagens do kernal do Linux pode ser interessante, porque parece que alguns membros da equipe do OP estão usando o Git de maneira semelhante.
@RibaldEddie disse em um comentário abaixo:
Primeiro, um stash não está fora de um "fluxo de trabalho de ramificação", pois sob o capô um stash é apenas outro ramo.
(correndo o risco de provocar a ira de muitas pessoas)
Linus disse:
Com o "git stash", você também pode ter várias coisas ocultas, mas elas não se alinham - são apenas patches aleatórios e independentes que você escondeu porque foram inconvenientes em algum momento.
O que eu acho que o @RibaldEddie está tentando dizer é que você pode usar git stash
em um fluxo de trabalho do ramo de recursos - e isso é verdade. Não é o uso git stash
disso que é o problema. É a combinação de comprometer-se a dominar e usar git stash
. Este é um anti-padrão.
Esclarecendo git rebase
Do comentário de @ RibaldEddie:
Rebasing é muito mais parecido com copiar e colar e ainda pior modifica o histórico confirmado.
(Ênfase minha)
Modificar o histórico de consolidação não é uma coisa ruim, desde que seja histórico de consolidação local . Se você refazer as confirmações que já enviou, essencialmente tornará órfão qualquer outra pessoa usando sua ramificação. Isto é mau.
Agora, digamos que você fez várias confirmações ao longo de um dia. Alguns commits foram bons. Alguns ... não é tão bom. O git rebase
comando em conjunto com esmagar suas confirmações é uma boa maneira de limpar seu histórico de confirmação local. É bom mesclar um commit para ramificações públicas porque mantém limpo o histórico de commit das ramificações compartilhadas da sua equipe. Após o novo rebasamento, você desejará testar novamente, mas se os testes forem aprovados, você poderá enviar um commit limpo em vez de vários outros sujos.
Há outro encadeamento interessante do Kernel Linux no histórico de confirmação limpa .
Mais uma vez, de Linus:
Quero uma história limpa, mas isso realmente significa (a) história limpa (b).
As pessoas podem (e provavelmente deveriam) refazer suas árvores privadas (seu próprio trabalho). Isso é uma limpeza . Mas nunca o código de outras pessoas. Isso é uma "história de destruição"
Portanto, a parte da história é bastante fácil. Há apenas uma regra principal e um pequeno esclarecimento:
Você nunca deve destruir a história de outras pessoas. Você não deve refazer o commit de outras pessoas. Basicamente, se ele não tiver sua assinatura, estará fora dos limites: você não poderá refazê-lo, porque não é seu.
Observe que isso realmente é sobre a história de outras pessoas , não sobre o código de outras pessoas . Se eles enviaram coisas para você como um patch enviado por e-mail e você aplicou com "git am -s", então é o código deles, mas é o
seu histórico.
Portanto, você pode se interessar pelo assunto "git rebase", mesmo que não tenha escrito o código, desde que o commit em si seja o seu particular.
Pequenos esclarecimentos à regra: depois que você publica seu histórico em algum site público, outras pessoas podem usá-lo e, agora, claramente não é mais o seu histórico privado .
Portanto, o menor esclarecimento é que não se trata apenas de "seu commit", mas também de ser privado da sua árvore, e você ainda não o divulgou.
...
Agora a parte "limpa" é um pouco mais sutil, embora as primeiras regras sejam bastante óbvias e fáceis:
Mantenha seu próprio histórico legível
Algumas pessoas fazem isso apenas pensando primeiro nas coisas e não cometendo erros. mas isso é muito raro e, para o resto de nós, usamos "git rebase" etc. enquanto trabalhamos em nossos problemas.
Portanto, "git rebase" não está errado. Mas é certo apenas se for a sua própria árvore git PRIVADA.
Não exponha sua porcaria.
Isso significa: se você ainda está na fase "git rebase", não o expande. Se não estiver pronto, você envia correções ou usa árvores git privadas (como uma "substituição de série de correções") sobre as quais você não fala ao público em geral.
(ênfase minha)
Conclusão
No final, o OP tem alguns desenvolvedores fazendo isso:
git checkout master
(edit files)
git commit -am "..."
(edit files)
git stash
git pull
git stash (pop|apply)
Existem dois problemas aqui:
- Os desenvolvedores estão se comprometendo a dominar. Bloqueie isso imediatamente. Realmente, este é o maior problema.
- Os desenvolvedores estão constantemente usando
git stash
e git pull
no mestre quando deveriam usar ramificações de recursos.
Não há nada de errado em usar git stash
- especialmente antes de um pull -, mas usar git stash
dessa maneira é um antipadrão quando há melhores fluxos de trabalho no Git.
O uso de git stash
um arenque vermelho. Não é esse o problema. Comprometer-se a dominar é o problema.