Parando desenvolvedores se comprometendo com a ramificação errada no DVCS


12

O problema

Estou em um projeto de software que tem cerca de 10 desenvolvedores, compartilhamos o código-fonte via Mercurial. Temos um ramo de desenvolvimento e produção por versão. Repetidamente, durante o curso do projeto, tivemos o código fonte de uma ramificação, ou seja, a v1, entrando nas ramificações de patches e manutenção para versões anteriores do software, ou seja, v2.

Isso resulta no tempo gasto no backup da confirmação incorreta ou no código errado (possivelmente não-QAd) atingindo e sendo implantado na ramificação errada, se não percebermos que o código foi para a ramificação errada.

Nossa filial e mesclar design / método

               v1-test   v1-patch1   v1-patch2
               ^---------^-----------^                v1-prod
              /         / \           \
-----------------------/   \           \              v1-dev
              \             \           \
               --------------------------\            v2-dev
                             \       \    \ 
                              ^-------^-------------  v2-prod
                              v2-test v2-patch1      

Portanto, trabalharemos em uma ramificação de desenvolvimento de versão, até que esteja pronta , ramificá-la para uma única ramificação de teste / UAT / Produção, onde todas as liberações e manutenção são feitas. Tags são usadas para criar versões deste ramo. Enquanto a v1 estiver sendo testada, uma ramificação será feita para a v2 e os desenvolvedores começarão a trabalhar em novos recursos.

O que tende a acontecer é que um desenvolvedor compromete o trabalho devido à ramificação v2-dev em v1-dev ou v1-prod, ou pior, mescla v2-dev em v1-prod (ou erros semelhantes).

Dizemos à maioria dos desenvolvedores para não acessar as ramificações -prod , mas o código ainda se infiltra. Um grupo de desenvolvedores mais seniores "cuida" da ramificação -prod.

Deve-se notar que, embora a v2 tenha acabado de iniciar o desenvolvimento, ainda existem alguns patches bastante pesados ​​entrando na v1 para corrigir problemas. Ou seja, a v1 pode não estar apenas recebendo o pequeno e estranho patch.

O que tentamos até agora

  • Ter um ramo -prod separado, com porteiros. Um ramo de produtos deve gerar avisos por meio de seu nome e a maioria dos desenvolvedores não precisa estar nesse ramo. Isso realmente não reduziu o problema.
  • Sensibilização para esse problema entre os desenvolvedores, para tentar torná-los mais vigilantes. Novamente, isso não teve muito sucesso.

Possíveis razões que vejo para os desenvolvedores que se comprometem com a ramificação errada

  • Projeto de filial muito complexo
  • Tendo desenvolvimento ativo em vários ramos em paralelo. (O projeto apresenta sintomas de uso do modelo de avalanche .)
  • Os desenvolvedores não entendem o DVCS o suficiente

Perguntas que li que eram de certa forma relevantes

Li esta pergunta sobre não me comprometer com o ramo errado e acho que as respostas sobre as dicas visuais podem ser úteis. No entanto, não estou totalmente convencido de que os problemas que estamos enfrentando não sejam sintomas de um problema mais fundamental.

Com as pistas visuais, podemos incorporá-las facilmente na linha de comando, no entanto, cerca de metade da equipe usa eclipse, o que não sei ao certo como incorporar pistas visuais.

Questão

Quais métodos, na forma de software, gerenciamento de projetos ou governança, podemos usar para reduzir (interromper, idealmente) as confirmações para o ramo errado, gastando nosso tempo ou sujando nosso código implantado?

Comentários específicos sobre as razões pelas quais acredito que podem estar contribuindo, conforme descrito acima, serão apreciados, mas isso não deve limitar sua resposta.


16
Você está tentando encontrar uma solução técnica para um problema social. Se você acha que o problema é que eles não entendem o DVCS, dedique algum tempo a treinar seu pessoal - será recompensado a longo prazo se você precisar perder tempo constantemente consertando fusões / confirmações ruins. Se você acha que o problema é que eles são desleixados e não se importam com o trabalho deles, isso é um problema de gerenciamento.
Sean McSomething

Em parte, é um problema de gerenciamento, mas também é uma ferramenta para permitir que os desenvolvedores façam escolhas sensatas.
Michael Shaw

Respostas:


22

O problema é que você está alterando qual o significado de uma ramificação durante o processo.

Inicialmente, o v1 devramo é para desenvolvimento. Todos os novos recursos vão para lá. Em algum momento no futuro, ele se tornará um ramo de manutenção para o v1 releaseramo. Este é o cerne do problema.

Não é que os desenvolvedores sejam desleixados, é que as permissões e funções do ramo são desleixadas e sujeitas a alterações.

O que você precisa fazer é estabelecer o papel de cada ramo e manter esse papel. Se a função mudar, ramifique.

Por exemplo:

 developer
  commits    |   |  |   |    |     |   |     |
             v   v  v   v    v     v   v     v
 dev  +--+---------------------+------------------->
         |           ^    ^    |           ^    ^
         |           |    |    |           |    |
 v1      +----+------+----+    |           |    |
           prod  patches       |           |    |
                               |           |    |
                               |           |    |
 v2                            +-----+-----+----+
                                  prod  patches

Nesse modelo, os desenvolvedores sempre se comprometem com o dev. Se você estiver criando um patch, verifique o patch na ramificação da versão (ou melhor ainda, ramifique a ramificação da release em busca de uma correção e depois a mescle novamente na ramificação da versão).

Um artigo que você deve ler (e provavelmente é um eufemismo para 'deveria') é o Advanced SCM Branching Strategies, de Stephen Vance.

Neste artigo, defino primeiro a ramificação em um sentido geral. Em seguida, discuto várias estratégias de ramificação, começando pelo óbvio e passando para várias que são mais apropriadas para maiores esforços de desenvolvimento. Ao longo do caminho, discuto os prós e contras de cada estratégia, usando-os para motivar as mudanças que compõem as estratégias mais complexas ...

Neste artigo, ele identifica cinco papéis que os ramos podem ter. Às vezes, uma ramificação pode preencher duas funções e as funções não precisam necessariamente de uma nova ramificação , desde que as políticas da função não sejam alteradas no meio da ramificação (você ocasionalmente verá a menção de "ramificação em políticas incompatíveis").

Essas funções são:

  1. Linha principal. É aqui que as ramificações são feitas. Sempre a ramificação da linha principal facilita as mesclagens, pois os dois ramos terão um ancestral comum que não é ramo após ramo após ramos.
  2. Desenvolvimento. É aqui que os desenvolvedores fazem o check-in do código. Pode-se ter vários ramos de desenvolvimento para isolar mudanças de alto risco daquelas rotineiras e mundanas.
  3. Manutenção. Correções de bugs em um ambiente de produção existente.
  4. Acumulação. Ao mesclar duas ramificações, é possível que você não queira arriscar desestabilizar a linha principal. Portanto, ramifique a linha principal, mescle as ramificações no acumulador e volte para a linha principal quando as coisas estiverem acertadas.
  5. Embalagem. Empacotar uma liberação acontece nas ramificações da embalagem. Isso geralmente se torna o release e serve para isolar o esforço de release do desenvolvimento. Consulte Como lidar com confirmações indesejadas que quebram compilações de versões de longa duração? para um exemplo de onde a embalagem entra em conflito com o desenvolvimento.

No seu exemplo, você tem uma linha principal em cascata (isso é um problema - torna as fusões mais difíceis - o que acontece se você deseja mesclar uma correção para v1 nas v2 e v3?), Uma ramificação de desenvolvimento que se torna uma ramificação de manutenção ( mudança de política, isso é um problema).

Ok, você diz, isso é ótimo, mas isso foi escrito para o forforce, que é um VCS centralizado - estou usando o DVCS.

Vamos olhar para o modelo git-flow e ver como ele se aplica.

O ramo mestre (azul) é o ramo de liberação - para marcação. Não é a linha principal. A linha principal é na verdade o ramo de desenvolvimento (amarelo). Os ramos de liberação (verde) são a função de empacotamento. O desenvolvimento de baixo risco ocorre na linha principal, o desenvolvimento de alto risco ocorre nos ramos do recurso (rosa). Nesse modelo, a acumulação é feita no ramo de desenvolvimento. A manutenção é considerada 'hot fixes', que são vermelhas.

Embora as políticas de função não sejam uma correspondência exata (cada produto tem seu próprio ciclo de vida ligeiramente diferente), elas são uma correspondência.

Fazer isso deve simplificar sua política de ramificação e facilitar para todos os envolvidos.


Uma ótima resposta técnica, pode funcionar se ele não a documentar, provavelmente não. É provável que o problema não seja totalmente resolvido, a menos que a estratificação de ramificação seja documentada com procedimentos claros.
mattnz

1
@mattnz Existem padrões de ramificação mais avançados (ghads, vou usar a palavra). No entanto, o 'todo mundo se compromete com o dev sempre' e 'quando estiver pronto, ramifique uma liberação do dev' deve levar você a 90% do caminho para a solução. Então, os únicos casos estranhos são 'trabalhando em um patch' e então é um "eu sei que estou fazendo isso em uma versão antiga, mude para esse ramo".

1
Aceitei esta resposta, pois ela formará a base das mudanças que faremos no nosso SCM. Os links para as Estratagias de ramificação avançadas do SCM e o modelo de fluxo git foram particularmente apreciados. Também tentaremos investir em treinamento para melhorar a compreensão de nossos desenvolvedores sobre o que eles fazem com o HG.
imp25

@ imp25 você pode achar o fluxo hg útil para o lado hg ao invés do git.

@ imp25 (e algumas perguntas e respostas StackOverflow sobre hgflow - stackoverflow.com/questions/14011921/… stackoverflow.com/questions/13021807/… )

3

Embora você tenha tentado usar uma ramificação -prod separada com gatekeepers, parece que o único repositório é usado para realmente criar a produção. Se as compilações de produção fossem feitas apenas a partir de um repositório de produção, gravável apenas pelo seu gatekeeper, os desenvolvedores não seriam capazes de avançar para ele. Isso sobrecarrega o gatekeeper, que só enviaria para o repo de produção após a revisão. É claro que as pessoas ainda seriam capazes de retirar do repositório de produção quando necessário.

À medida que as pessoas ganham experiência, elas devem ser rotacionadas através do papel de guardião, para obter um entendimento ou cuidado mais profundo que parecem não ter.

Como regra geral, aplique o Navalha da Occam: toda a estrutura do repositório deve ser o mais simples possível para fazer seu trabalho.

Veja também o comentário de Sean.


2

É possível que os desenvolvedores simplesmente não obtenham o DVCS suficientemente bem, mas acho que é muito mais provável que você simplesmente faça muita coisa, e os desenvolvedores não conseguem acompanhar o que estão fazendo de momento a momento. Eles esquecem em que ramo eles deveriam estar trabalhando e suas mudanças acabam no lugar errado.

Eu sugiro que você tenha um problema com o fato de que todos estão trabalhando em todos esses ramos regularmente.

A sugestão de @ andy256 de um repositório separado para prod certamente ajudaria, mas você pode precisar dividir o trabalho de maneira diferente ou talvez organizar coisas para que nenhum desenvolvedor trabalhe em mais de um ramo em uma determinada semana.


1

Parece que você identificou um dos meus principais insetos. A maioria das ferramentas de controle de origem é exatamente isso, ferramentas de controle de origem. Eles permitem que vários desenvolvedores trabalhem no mesmo diretório de origem, fazendo alterações e lidando com conflitos. Houve algumas arestas ao longo do caminho, mas cvs, subversion, git, mercural etc tudo isso.

Depois, você tem o próximo passo, quando precisa estabilizar o código para lançamento, e introduz a ramificação. É aqui que as ferramentas começam a falhar com os desenvolvedores. As ferramentas são capazes de fazer a ramificação e até mesmo identificar os conjuntos de alterações acumuladas nas ramificações depois de ramificadas, mas esse não é o problema que você enfrentou agora.

As ferramentas são realmente ruins na seleção de quais alterações precisam ser copiadas para outras ramificações e quando isso precisa ocorrer. O Git-flow tenta resolver isso criando uma estratégia de ramificação que significa que quando as ramificações são mescladas, TODAS as alterações são mescladas e exige que o programador faça escolhas sensatas sobre quando e quais ramificações serão mescladas.

Em um único repositório em que todos os desenvolvedores estão trabalhando em um projeto que possui um único encadeamento de lançamento, o git flow resolve o problema, mas a vida não é tão simples para muitas empresas.

O ambiente complexo é onde você tem várias equipes responsáveis ​​por diferentes aspectos da solução total, executando releases internos para outras equipes. O git-flow simplesmente não é capaz de resolver esse tipo de problema.

A única maneira de ver esse trabalho é se cada equipe é responsável por definir seus lançamentos e controlar quando suas dependências mudam. Só porque a equipe A lançou a versão 1.3, a equipe B começa a usar a versão 1.3 da equipe A quando a equipe B escolhe.

Com efeito, uma equipe de desenvolvedores define os grupos de alterações que precisam ser movidos, e os desenvolvedores que recebem as alterações definem quando recebem o grupo de alterações.

A única ferramenta de controle de origem que vi que realmente fornece isso é precisa - e mesmo assim, a maioria dos seus desenvolvedores se queixam disso, porque a GUI é muito confusa para eles e não se comporta como subversão ...

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.