Pergunta

Vamos dizer que você tem vários ramos de manutenção para as versões existentes do seu software. Alguns desenvolvedores estão fazendo mudanças diretas nos ramos de manutenção, e fundindo periodicamente para o tronco. Agora vem uma extensa refactoring na codeline tronco, prevista para um grande lançamento próximo. Mas isso faz com que os ramos de manutenção fundamentalmente incompatíveis com o código no porta-malas, pois eles podem depender de código que não existe mais, por exemplo.

Como você lida com essa situação na prática?

Foi útil?

Solução

Eu gostaria consideram a responsabilidade do desenvolvedor de manutenção ramo de mesclar a alteração apropriada para o estado atual do tronco. Existem várias possibilidades:

  1. O código no porta-malas não mudou e o patch aplica-se sem conflitos.
  2. O código no tronco mudou e o patch aplica-se, mas com uma mesclagem manual do necessário.
  3. O código no tronco mudou completamente eo patch não pode aplicar. O desenvolvedor deve avaliar se o mesmo defeito existe no tronco, e aplicar uma correção equivalente, se necessário.

Casos 1 e 2 são os caminhos habituais de desenvolvimento manutenção. Caso 3 é o caso que você está considerando, onde o código tronco não pode aceitar o patch de manutenção em qualquer forma. Se o desenvolvedor não pode-se determinar se o mesmo problema pode existir no porta-malas, então ele deve entrar um problema no sistema de gerenciamento de incidentes. Esta questão iria dirigir os desenvolvedores tronco considerar a razão para o patch no ramo de manutenção e se o mesmo defeito pode ainda existir. Introduzir um novo problema para um possível defeito no tronco deve ser um último recurso para o desenvolvedor de manutenção.

Uma das vantagens de ter desenvolvedores de manutenção tentar aplicar patches para o tronco atualizado é de aumentar a sua familiaridade com a nova base de código. Eventualmente, eles vão ficar sem trabalho de manutenção e terá de trabalhar com o novo tronco. Tendo pelo menos um nível básico de familiaridade será de grande benefício.

Outras dicas

Este é, finalmente, uma pergunta sobre a comunicação da equipe, ao invés de uma ramificação / pergunta fusão simples.

O primeiro passo, como em todos os casos, é perceber que você tem um problema. Isso é algo que você fez.

Em seguida, você precisa para alertar toda a equipe para a questão.

Uma vez feito isso, eu acho que existem dois caminhos diferentes:

  1. Se os ramos de manutenção são utilizados com pouca frequência, dizem que o código liberado é bastante madura e livre de bugs, você pode decidir sobre um congelamento de código. Cada desenvolvedor deve terminar o que ele / ela está trabalhando em pelo 32 Octember, e mesclar essas alterações de volta para o tronco. Os ramos devem, então, ser fechadas ou congelado. Então, o trabalho pode continuar no tronco, e o novo software pode ser liberado.

  2. Se houver alterações e correções freqüentes ou urgentes nos ramos, esta questão é mais complicada. Há ainda precisa ser um congelamento do código, ou o tronco será derrotado várias vezes. Mas aqui, os desenvolvedores ainda precisam consertar as coisas nesse ínterim e levá-los aos clientes. Eu sugiro que cada mudança nos ramos após o congelamento do código tronco devem ser registrados no banco de dados de rastreamento de bugs (uma obrigação em cada situação) com uma indicação especial que este foi fixado no ramo N, mas ainda não se fundiram para o tronco. Isso requer o registo cuidado para que cada detalhe relevante é lembrado.

    Depois do tronco é reformulado, mas antes que ele é limpo, polido, etiquetado, e liberado, rever a base de dados de erro, particularmente os itens fixos nos ramos, mas não o tronco. Eles ainda são relevantes? Agora é a hora de mudar o código novamente, se necessário. Isso pode significar trabalho em dobro por um curto tempo, mas espero que o código é muito mais sustentável agora.

    Uma vez que todos os problemas conhecidos são fixos, a nova versão pode ser liberado, e os antigos ramos pode ser fechado.

A única resposta que tenho sido capaz de chegar a é criar um ramo de manutenção-tronco pouco antes de começar a refatoração. Você manter este novo ramo como se fosse um tronco, fundindo mudanças para e de ramos de libertação como normal. Daqui para frente, então você tem que ter cuidado sobre a mistura de mudanças das antigas e novas bases de origem.

A outra alternativa é tentar algo como MolhadoRef ( artigo no blog sobre MolhadoRef e refatoração-aware SCM ), se você pode encontrar um pronto-para-produção sistema equivalente que atenda às suas necessidades. Esta é, em teoria, refatoração-aware controle de origem. Eu não olhei para ele em um tempo, mas durar Lembro-me ainda era bastante longe de ser mais qualquer coisa do que um trabalho de pesquisa e prova-de-conceito.

Na prática, você pode ter que fazer trabalho extra para fazer suas novas alterações compatíveis com versões anteriores.

  • Passo 1: Iniciar refatoração do componente. A cada passo, manter a interface antiga volta, mas tê-lo migrar chamadas para a nova implementação. Note que isso pode ser feito em várias etapas como a nova interface / API é construída. Os testes de unidade deve ser capaz de verificar se a migração de antigos para novos trabalhos corretamente, mas este passo provavelmente irá ainda incorrer testing / QA sobrecarga.

  • Passo 2: A nova versão é ao vivo na produção; garantir que todos saibam sobre isso. Neste ponto, há novos recursos são adicionados à versão antiga, e todos os novos (ou alterados) chamadores usar a nova versão.

  • Passo 3: Encontre tudo (ferramentas usar para fazer isso) que chama a interface antiga, e mudar tudo para chamar a nova interface. Isso provavelmente incorre em uma série de testes / QA em cima, também. Cada chamada pode ser cometido / lançado um de cada vez, no entanto.

  • Passo 4: Neste ponto, a nova versão é ao vivo, e não há chamadores deixou que o acesso a versão antiga. Excluí-lo com segurança.

Note que, quando o API é pública e você não controlar as pessoas que o chamam de (empresas como a Microsoft, por exemplo), você nunca pode ser capaz de ir passo passado # 2.

Este processo pode ser lento, e que exige muita disciplina, comunicações, e testes. Mas nos casos em que a alternativa está jogando catch-up / integração para sempre, pode ser uma opção razoável.

Tendo em conta que uma grande parte do custo de corrigir um bug está reproduzindo o problema e testar a correção. você pode escrever um teste automatizado que irá funcionar em todos os ramos, mesmo se a correção de código tem que ser feito de forma diferente para cada ramo?

No ponto em que seus ramos de manutenção já não é compatível com o tronco principal são, seria hora de criar novas agências para o efeito. Ou seja, no início do projeto grande, você certificar-se de todos os seus desenvolvedores estão cientes de que a nova funcionalidade está chegando no tronco principal, para que eles possam fazer uma melhor escolha de onde implementar correções. Presumivelmente, se as alterações de código que ocorrem no tronco principal são tão significativo como a tornar a manutenção não-suportáveis, em seguida, a manutenção deve ser incorporado no tronco principal.

Criar um ramo de manutenção e tê-lo agir como um amortecedor entre o tronco e a versão de ramos.

As alterações à versão-ramos entrar no ramo de manutenção e, em seguida, propegate no tronco somente se eles podem e vice-versa.

Eu não acho que há uma bala de prata, no entanto. Como ramos divergem cada vez mais, eles vão crescer incompatível e por isso você tem que considerar por quanto tempo você vai apoiá-los. Caso contrário, você pode acabar corrigir bugs mais de uma vez, mas um pouco diferente para os vários ramos.

Esta pode ser uma muito trabalho sugestão intensivo, mas a primeira coisa que vem à mente para mim está se fundindo tudo de volta ao tronco. mudanças de todos voltar mesclado para a cópia tronco e mantê-los todos juntos. Em seguida, refatorar no tronco como quiser. Agora você tem um tronco de trabalho, com todas as correções juntos.

Infelizmente, isso significaria que quaisquer correções nos ramos manutenção precisaria ficar jogado juntos e no tronco central. Sei que isso seria um monte de trabalho, mas acho que isso permitiria tudo para ser reformulado, e quaisquer melhorias nos ramos manutenção pertenceria no ramo principal. Eu posso ser ingênuo sobre isso, mas eu realmente não tenho trabalhado em um projeto de produção, e também não sei exatamente o que está nos ramos manutenção. Eu acho que isso tornaria o tronco totalmente atualizado e todas as suas melhorias manutenção seria integrado no porta-malas.

Eu acho fazê-lo desta forma seria maximizar a qualidade de todos os seus ramos e ter o seu refatoração distribuídos por todos os ramos que seria de filial após a refatoração. Esta seria uma boa maneira de trazer a sua equipe para todos da fusão, também.

Eu vejo dois caminhos diferentes para resolver este:

1.

Alterações significativas para o tronco (como um grande refactoring) não deve ser feito no porta-malas. Eles devem ser feitas em um ramo e mescladas de volta para o tronco quando são bastante estável.

Periodicamente, as alterações no tronco deve ser mesclado com outros ramos de manutenção. A razão por apenas fundindo a refatoração no tronco quando é estável é porque estes irão, em seguida, ficar colada com os ramos de manutenção. Se, contudo, não há oportunidade para fazer essas mudanças estável, em seguida, a opção 2 seria melhor.

Depois de mudanças para os ramos de manutenção foram feitas podem então estar de volta incorporada no tronco.

2.

Criar um ramo dos ramos de manutenção (um ramo para cada). Isso será usado para mesclar o tronco com cada ramo de manutenção. (Note-se que o uso de fatores externos SVN ou equivalente devem ser usados ??a fim de limitar o número de agências de manutenção).

Faça todo o seu refatoração no tronco e mesclar esta para os ramos dos ramos de manutenção. Quando você soltar ou pensar que o tronco é estável em seguida, mesclar esses ramos das versões de manutenção de volta em seus respectivos ramos. Estes podem, por sua vez estar de volta incorporada no tronco.

Com efeito cada ramo de manutenção se torna um "sub tronco".

Note que este cenário destaques o trade-off entre a manutenção futura e manutenção inicial. Os mais ramos e diferenças que você tem em seu código a manutenção mais adiantado é necessário. A parte boa é que a manutenção incremental é muito mais fácil.

Posso apenas refletem o que outros disseram, sublinhando a verdadeira dor no a $$ que as filas de patch pode se tornar.

Se você tem uma janela de mesclagem pré-definidos (e folheados de ferro), você deve ter apenas duas semanas de inferno para lidar com eles.

Eu acho que sua melhor opção é ter iterativo refatoração. Em vez de fazer toda a refatoração em um grande tiro no seu próprio ramo, faça-o uma fase de cada vez. Fazer alguns conjuntos de alterações no ramo e, em seguida, quando você sabe que eles são estáveis, fundi-los para o tronco. Os desenvolvedores que trabalham em outros ramos seria responsável por manter continuamente seu ramo atualizado com o tronco.

Mesclando um pequeno conjunto de mudanças muitas vezes vai ser muito menos trabalho do que mesclagem grandes ramos que diferem um pouco. Quanto mais vezes você mesclar, o trabalho menos você terá que fazer no final.

Em nosso projeto, nós não corrigir principalmente mudanças em ramos de manutenção versão. Se há um erro e

  1. ocorre tanto no tronco e do ramo principal, nós corrigi-lo no porta-malas e, em seguida, mesclar a mudança para o ramo de manutenção (que pode einther acontecer de forma limpa, ou exigir mais trabalho, caso em que decidimos se não é melhor não ter o bug corrigido no mais recente versão apenas).
  2. é apenas no ramo de manutenção, provavelmente há algum rei de correção no porta-malas e ir para o número scenation um.

Você tem que Have que muitos ramos sendo trabalhado?

Foi trabalho no tronco só começou quando o fez porque o plano do projeto disse que a versão atual seria pronto para enviar, por isso, foi enviado?

Você tem muitos ramos de manutenção porque os clientes se recusam a atualizar para a versão mais recente por algum motivo? Se assim abordar a razão.

Você tem muitas versões antigas Becouse a lacuna antes da próxima versão principal é muito grande?

Você cobrar os clientes que não vai atualizar mais para manutenção, uma vez que custar-lhe mais?

resposta ao comentário:

Microsoft ainda suporta o Windows XP embora Vista está fora

É muito verdadeiro, no entanto Microsoft não continua a apoiar o Windows XP SP1, embora XP SP3 está fora.

Esta não é a preto e branco, mesmo que você não pode deixar de apoiar versão antiga, você pode ser capaz de reduzir o número de versões antigas que suportam. O problema é que as vendas / Suporte gosta de dizer sim, mas o desenvolvimento começa a dor, então você precisa para começar suas vendas / apoiar as pessoas do lado.

Como Greg apontou existem vários cenários possíveis.

Eu adicionaria um caso (2,5), onde é necessária merge manual, mas uma vez que você se moveu um método de distância de sua localização original e, em seguida, aplicado algumas mudanças, torna-se difícil de fundir, especialmente se o código "base" também foi modificado no ramo "manutenção". Isso não é tão incomum quanto parece, de fato movendo um método para um local diferente e aplicando uma pequena correção é bastante comum.

Nós desenvolvemos uma ferramenta chamada Xmerge (cross-merge), que é um primeiro passo para a fusão refactor-aware. Ainda não é automático, mas ajuda a lidar com fusões complexas em código movido. É descrito aqui e já está integrado no Plastic SCM 2.7.

Estamos trabalhando em: detecção de movimento automático e também ser capaz de "merge cruz" no sentido de vários arquivos de destino (que você mover o código para outro arquivo, que também é bastante comum)

.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top