Recentemente, observei como eu e minha equipe usamos o Git e como nossos fluxos de trabalho funcionam. Atualmente, usamos um fluxo de trabalho de ramificação de recursos que parece funcionar bem.
Também vi algumas pessoas em nossa equipe usarem o fluxo de trabalho com base no git stash . O fluxo de trabalho é mais ou menos assim:
- Trabalhar em uma ramificação principal (como
master
) - Faça confirmações à medida que avança
- Se você precisar fazer alterações ou alternar ramificações, empurre as alterações não confirmadas para o esconderijo
- Depois que a atualização estiver concluída, retire as alterações do esconderijo.
Devo mencionar que esse fluxo de trabalho é usado em vez de um fluxo de trabalho da ramificação do recurso. Em vez de pegar uma ramificação e trabalhar nela, os desenvolvedores aqui apenas trabalham em uma única ramificação e empurram / saem da pilha como bem entenderem.
Na verdade, não acho que esse seja um ótimo fluxo de trabalho, e a ramificação seria mais apropriada do que usar o git stash dessa maneira. Consigo ver o valor do git stash como uma operação de emergência, mas não para usá-lo em um fluxo de trabalho diário e regular.
Usar o git stash regularmente seria considerado um anti-padrão? Em caso afirmativo, quais são alguns problemas específicos que podem surgir? Caso contrário, quais são os benefícios?
If you need to get changes or switch branches, push your uncommitted changes onto the stash
- é exatamente para isso que serve.Respostas:
Do livro do Git SCM :
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.
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:
(correndo o risco de provocar a ira de muitas pessoas)
Linus disse:
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 usogit stash
disso que é o problema. É a combinação de comprometer-se a dominar e usargit stash
. Este é um anti-padrão.Esclarecendo
git rebase
Do comentário de @ RibaldEddie:
(Ê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:
(ênfase minha)
Conclusão
No final, o OP tem alguns desenvolvedores fazendo isso:
Existem dois problemas aqui:
git stash
egit 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 usargit 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.fonte
Pessoalmente, uso apenas
stash
interrupções curtas e inesperadas, como alguém que faz uma pergunta que exige a mudança para um ramo diferente. Faço isso porque esqueci os esconderijos antes, então eles não se aplicavam corretamente. As confirmações regulares nas ramificações dos recursos são muito mais difíceis de esquecer e mais fáceis de mesclar, então agora eu costumo fazer apenas uma confirmação quebrada, depoisgit reset HEAD~1
refizo ou refizo se não quiser mantê-la mais tarde.No entanto, o melhor do controle de versão distribuído é que as pessoas podem usar seu fluxo de trabalho preferido em seus próprios repositórios, desde que os repositórios compartilhados atendam aos padrões. Eu garantiria que as pessoas não usassem apenas um
stash
fluxo de trabalho porque não têm treinamento ou conhecimento suficiente de alternativas, mas se ainda escolherem um fluxo de trabalho que você considera subótimo, eu deixaria como está.fonte
Acho que a parte da sua pergunta que é um antipadrão é o uso de um único ramo mestre compartilhado . No entanto, se você incluir uma ramificação de desenvolvimento além da ramificação principal e, em seguida, usar stashes para lidar com suas próprias alternâncias de contexto na ramificação de desenvolvimento, isso não seria um antipadrão e reflete muito de perto alguns fluxos de trabalho. descrever por organizações como Etsy e Facebook.
Dito isto, a resposta de @Greg Burghardt acima é um pouco favorável ao chamado fluxo de trabalho git-flow ou feature-branch. Eu defendia uma estratégia semelhante, mas depois de perceber que ela adiciona complexidade desnecessária e cria uma falsa sensação de segurança, não o faço mais. É também uma ressaca dos dias de sistemas de controle de versão não descentralizados, como o subversion.
Primeiramente, como o Git é um sistema descentralizado de controle de versão, diferentemente do subversion, o repositório local de um desenvolvedor é essencialmente um ramo gigante do código em si. O que um indivíduo desenvolve localmente não tem e não deve ter impacto nos outros membros da equipe, a menos que o código quebrado ou com bugs seja enviado para qualquer ramificação compartilhada em um repositório compartilhado.
O comando rebase, no entanto, pode danificar o histórico da ramificação quando houver um conflito de mesclagem em uma das confirmações reproduzidas. De http://ryantablada.com/post/the-dangers-of-rebasing-a-branch
Além disso, um modelo de ramificação múltipla pressupõe que nenhuma ramificação jamais poderia conter alterações de código interdependentes. Quando isso acontece inevitavelmente, o desenvolvedor agora precisa conciliar ainda mais filiais para trabalhar com eficiência.
O anti-padrão fundamental que vejo não está relacionado a ramos versus esconderijos, mas sim mais aos tipos de problemas que algumas pessoas muito inteligentes têm falado há um tempo: você confia no seu código através do uso de testes de unidade e uma boa arquitetura? Você é capaz de fazer alterações incrementais no seu código, de modo que seus desenvolvedores possam raciocinar sobre alterações facilmente e entender o que uma alteração fará? Seus desenvolvedores executam o código uma vez para ver se ele realmente funciona? (Sim, eu já vi isso antes).
Se a resposta a essas perguntas for negativa, não importa quantas ramificações você tem - os desenvolvedores dirão que o código está pronto, funcionando e adequado para produção quando realmente não é, e não há número de ramificações. ajudá-lo quando esse código chegar à produção de qualquer maneira.
fonte
git stash
é uma ferramenta. Por si só, não é um padrão, nem um antipadrão. É uma ferramenta, assim como um martelo é uma ferramenta. Usar um martelo para acionar pregos é um padrão e usar um martelo para acionar parafusos é um antipadrão. Da mesma forma, existem fluxos de trabalho e ambientes ondegit stash
é a ferramenta correta a ser usada, e fluxos de trabalho e ambientes onde estão incorretos.O fluxo de trabalho 'todos comprometem e enviam para a linha principal' é aquele que funciona razoavelmente, onde não há alterações de alto risco. É frequentemente visto usado em ambientes svn, onde há um servidor central autorizado que possui o código.
O Git, no entanto, vincula-se a acabar com o único servidor central. Ter todos os desenvolvedores a fazer
commit
,pull
(ourebase
se você estiver em que),push
todo o tempo podem fazer uma grande bagunça.Os maiores problemas surgem: você tem algo em andamento que está quebrado e precisa trabalhar em um bug prioritário. Isso significa que você precisa deixar esse trabalho de lado por um tempo, pegar o mais recente, trabalhar nele sem que o trabalho anterior em andamento cause problemas com a compilação que você está tentando fazer.
Para isso,
git stash
seria a ferramenta adequada para usar.Há, no entanto, um problema maior oculto no coração desse fluxo de trabalho. É que todas as funções das ramificações de controle de versão estão em uma única ramificação. Linha principal, desenvolvimento, manutenção, acumulação e embalagem estão todos no Master. Isso é um problema. (Consulte Estratégias avançadas de ramificação do SCM para obter mais informações sobre essa abordagem de filiais)
E sim, você disse que não é um ótimo fluxo de trabalho e que há problemas com ele. No entanto, o problema não está na ferramenta
git stash
. O problema é a falta de ramificação distinta para funções ou políticas incompatíveis .git stash
no entanto, é algo que eu usei quando tive uma situação em que construí um pouco, entrei em um estado difícil que não tinha certeza se era o certo ... então escondi minhas alterações e depois explorou outra abordagem para resolver o problema. Se isso funcionou - ótimo, descarte o material no estoque e continue. Se a outra exploração ficar mais complicada, redefina a alteração anterior e aplique novamente o estoque para trabalhar nisso. A alternativa seria confirmar, finalizar a compra, ramificar e continuar nessa nova ramificação ou voltar e redefini-la. A questão é: vale a pena colocar isso na história quando é apenas algo que eu quero explorar um pouco?git stash
não é um anti-padrão. Usargit stash
como alternativa à ramificação enquanto todos se comprometem com o Mestre é um anti-padrão - mas não por causa dissogit stash
.Se você ainda não o encontrou, aguarde até ter problemas com as compilações , quando alguém precisar fazer alterações arquiteturais significativas em muitos arquivos (e os conflitos de mesclagem) ou algum código de trabalho em andamento não testado que vaza para produção para este anti-padrão para alcançá-lo.
fonte