Um modelo de ramificação git decente para produtos que devem acompanhar a versão de outro produto de terceiros (e prós e contras de uma proposta)

13

Nota: Minha pergunta está focada no meu problema específico (que envolve o Liferay), mas espero que possa ser útil para quem precisa manter várias versões de um mesmo projeto no git.

Eu trabalho em uma empresa que escreve muitos plugins para o Liferay Portal . Esses plugins (portlets, temas etc.) geralmente são reutilizáveis ​​e, é claro, devem ser atualizados para novas versões do portal.

No entanto, é comum ter que migrar, digamos, um portlet para uma nova versão do Liferay e manter sua versão anterior. Além disso, frequentemente precisamos criar personalizações muito específicas para alguns clientes, o que não faz sentido para ser adicionado à "versão principal".

Esses requisitos complicam nosso trabalho, mas, felizmente, podemos assumir algumas simplificações. Por exemplo, os plugins são atualizados com freqüência por apenas um programador por vez. É muito raro ter dois ou mais recursos sendo adicionados a um plug-in ao mesmo tempo.

Agora, estamos migrando para Gitorious . Estamos tentando conceber um modelo de ramificação para esse cenário.

Meu modelo

O que eu propus foi:

  1. Cada plug-in teria seu próprio repositório no Gitorious dentro de um projeto. Por exemplo, um portlet para exibir gatinhos teria um kittens-portletrepositório dentro do liferay-portletsprojeto.
  2. Ao criar um novo plug-in, crie-o em uma ramificação nomeada de acordo com a versão do Liferay (por exemplo, lf5.2).
  3. Sempre que uma atualização é feita no plug-in, a atualização é aprovada e implantada na produção, marque o plug-in com uma versão (por exemplo lf5.2v1, lf5.2v2etc.) *
  4. Sempre que um plug-in deve ser portado para uma nova versão do Liferay, ramificamos a versão mais recente (criando, por exemplo, a ramificação lf6.0).
  5. Uma vez em produção, o chefe da nova filial receberá uma tag como lf6.0v1.
  6. Sempre que precisamos personalizar um plug-in de uma maneira específica do cliente, criamos uma filial com o nome do cliente (por exemplo, criaríamos uma filial lf5.2clientcorppara o nosso cliente "ClientCorp Inc.")

Esse é um modelo incomum: ele não teria mastermuitos ramos que não se fundem. É assim que suponho que um repositório com esse modelo se pareceria com:

Como suponho que meus ramos funcionariam.

Um amigo achou esse sistema bastante complexo e propenso a erros. Ele sugeriu o excelente e popular modelo de Vincent Driessen , que achei ainda mais difícil de gerenciar e disciplinar. É ótimo (e testado!), É claro, mas parece complexo demais para a nossa situação.

Modelo do meu amigo

Em seguida, ele sugeriu outro modelo: teríamos um repositório para cada plugin em uma versão do Liferay (para começarmos a criar um kittens-lf5.2-portlete depois a kittens-lf6.0-portlet), cada um com um masterramo e um developramo. O masterestaria sempre pronto para implantação. (Ou pode ser o contrário mastere stable, como sugerido por Steve Losh ).

Isso é muito simples, mas eu não gostei deste sistema:

  1. isso pode resultar em muitos repositórios em um projeto, dificultando a navegação no Gitorious.
  2. O nome do diretório do projeto é relevante. Se alguém clonar o repositório em um kittens-lf6.0-portletdiretório e gerar o WAR com ant (como de costume), o nome do WAR também será kittens-lf6.0-portlet. As versões antigas deste portlet (nomeadas kittens-portletpor exemplo) seriam consideradas portlets diferentes (e provavelmente ausentes) em um portal atualizado. Um pouco de cuidado pode evitá-lo, mas eu preferiria evitá-lo.
  3. As diferentes versões do mesmo plugin seriam mantidas separadas. Eu quebro meu coração :(
  4. kittens-lf6.0-portlet é um nome feio para um repositório, eu acho.

Suspeito que os dois últimos pontos - que também são os mais subjetivos - sejam a principal razão da minha falta de vontade. No entanto, todas as quatro objeções permanecem.

OTOH, minha própria proposta parece estranha para mim e me pergunto se há bugs ocultos nela. O OT3rdH git é tão poderoso e flexível que acho que não deveria ter vergonha de explorar suas possibilidades.

Então eu pergunto:

  1. Qual seria o melhor modelo? Minha proposta? Modelo do meu amigo? O agora tradicional sistema Vincent Driessen?
  2. Que outro modelo de ramificação você sugeriria?
  3. Se você acha que meu modelo é ruim, por que você acha? Gostaria muito de saber quais são as desvantagens e pontos cegos.

* Na verdade, eu preferiria marcar o commit com uma versão como, v1mas aparentemente um tag no git não está no escopo da ramificação - ou seja, eu não poderia ter uma v1tag 1 lf5.2e outra dentro lf6.0- então eu tenho que nomear o ramo. BTW correto?

brandizzi
fonte
No seu modelo, com que frequência você precisa adicionar o mesmo recurso ou correção de bug a várias ramificações?
Karl Bielefeldt
@KarlBielefeldt Na verdade, é raro. Um bug em uma versão do portal geralmente não faz sentido em outra versão e é reparado durante a migração. A versão anterior não é corrigida ao mesmo tempo, exceto se o cliente solicitar. Um plug-in customizado pelo cliente poderia, em teoria, receber o novo recurso / correção de bug, mas eu nunca vi isso, mesmo porque as ramificações do cliente são um último recurso raro: tentamos generalizar o plug-in em vez de personalizá-lo de uma maneira específica do cliente. Portanto, minha experiência é que é incomum obter modificações de um ramo para outro.
Brandizzi

Respostas:

2

Se eu li isso corretamente, as ramificações são basicamente um desvio único da sua linha principal de desenvolvimento, que nunca deve ser mesclada de volta à linha principal e os avanços na linha principal nunca são aplicados a essas ramificações. O único desvio seria que as correções de bugs apropriadas à versão em que a ramificação se baseava precisassem ser aplicadas à ramificação.

A resposta agora gira em torno do seu fluxo de trabalho diário, o número de desenvolvedores trabalhando em qualquer ramo ou o número de alterações são sinais negativos. Vejo sua necessidade principal como querer saber quais ramificações recebem uma atualização de correção de bug de uma alteração de ramificação principal e, para isso, acho que o repositório combinado com ramificações será mais eficiente, pois está tudo em um só lugar. Como nunca houve necessidade de polinização cruzada, os repositórios separados exigiriam isso, mas esse cenário não corresponde à realidade do seu projeto como eu o entendo.

O modelo Driessen funcionaria bem se o seu projeto precisasse mesclar ramificações de volta à linha principal de desenvolvimento, mas você não precisa disso. Mesmo assim, acho que há mérito em manter o conceito InDevelopment e StableRelease se você estiver trabalhando em um produto que está ativo.

Então, para resumir, acho que seu projeto funcionaria bem com seu modelo de ramificação, mais uma pitada de Driessen para sua linha principal. Sua milhagem pode variar; Eu sempre trabalhei com um ramo de "release pendente" que se transforma em um ramo "ativo" e um "próximo release" separado, que exige polinização cruzada de correções e alterações em vários pontos, para que minha percepção seja tendenciosa.

Patrick Hughes
fonte
3

O que me impressiona é o fato de que cada portlet possui seu próprio repositório (mas sua história pode não estar completa). Pessoalmente, eu criaria um repositório por projeto. Os projetos geralmente têm vários portlets e são todos compilados na mesma execução na mesma versão do Liferay. Cada projeto pode ser uma duplicata de um projeto existente que é compilado em uma versão diferente do Liferay, mas eu só dividiria um produto se as diferenças fossem grandes demais. Se uma compilação funciona com o Liferay 5.1 e 5.2, eu não dividiria o projeto. Eu usaria scripts ou Maven (ou ambos) para deixar tudo funcionar. Eu usaria um Wiki (ou Trello) para gerenciar cada produto e com qual versão do Liferay ele pode ser construído.

A propósito: Sou programador Java, especialista em Maven, especialista em build e tenho experiência com o Liferay e outros servidores de portal (IBM WebSphere e Glassfish).

Mas este é apenas o meu € 0,02.

Ivo Limmen
fonte