Estratégia para usar o controle de versão em um sistema modular

15

Vamos supor (por simplicidade) que temos um aplicativo com cliente e servidor; existe uma idéia melhor para usar um repositório para ambos ou um par de repositórios separados?

Misturá-los provavelmente facilitará o rastreamento de alterações correlacionadas e manterá ramificações correlacionadas (ou seja, evolução do protocolo), mas, por outro lado, tornará o desenvolvimento individual mais desorganizado ...

mbq
fonte
E o que há de errado em usar ramos separados? Um desenvolvedor só precisa ter o ramo em que está trabalhando atualmente localmente, para que ele nem veja as coisas que estão apenas nos outros ramos. Mas, se ele precisar entrar no ramo por algum motivo, ele pode.
Spencer Rathbun
@ SpencerRathbun - Usar ramos separados como este é uma receita para o desastre . Seria realmente difícil compartilhar arquivos entre servidor e cliente, especialmente interfaces e documentação do sistema etc. Com um DVCS, seria necessário clonar todos os commits do cliente e do servidor, mesmo que você apenas desejasse um e não o desse. qualquer dica sobre quais versões de cliente e servidor funcionariam juntas. Comparado a um repositório monolítico (único) ou a uma repartição modular (vários), você realmente obtém o pior dos dois mundos .
Mark Booth
@ MarkBooth Humm, eu estava pensando nas seções do projeto em cada filial, pois ele indicou que elas compartilharão código. Apenas marque cada seção como os ramos apropriados e você estará bem. Seu DVCS não permite que um arquivo / confirmação tenha várias tags?
Spencer Rathbun

Respostas:

12

Se você estiver usando git ou mercurial , convém examinar sub - módulos ou sub - repositórios .

O cliente, o servidor e seus arquivos de interface estariam em seus próprios repositórios, mas seriam vinculados no nível do super-repositório . Isso permitiria que você fizesse uma verificação geral no nível superior e gitou hgverificasse a confirmação apropriada de cada um dos sub-módulos / sub-repositórios.

Comprometendo-se apenas com o super-repositório quando o cliente e o servidor eram apropriados um ao outro, o super-repositório só lhe dava a opção de verificar um sistema em funcionamento - para que você nunca tentasse executar o novo cliente em um antigo servidor ou vice-versa.

Sub-módulos / sub-repositórios oferecem todas as vantagens do uso de repositórios separados, além das vantagens de um único repositório monolítico, às custas de um pouco de complexidade extra.

Essa resposta não se destina a defensora gitou hgsobre outros SCMs, que só acontece de ser que eu só conheço essas SCMs bem o suficiente para saber que esta opção existe. Eu não entendo como svnexternos funcionam, por exemplo.

Mark Booth
fonte
1
Agora, isso é um recurso interessante. Eu estaria interessado em ver alguns estudos de caso adequados sobre o seu uso, eu nunca tinha ouvido falar disso antes!
Ed James
Uma coisa semelhante no subversion são as definições externas: svnbook.red-bean.com/en/1.0/ch07s03.html . No entanto, funciona de uma maneira ligeiramente diferente.
Liori
1
@ MarkBooth: sim, você pode. Nessa página, você pode ver parâmetros parecidos com -r12345 - aqueles que definem qual revisão você deseja obter. E como a propriedade svn: externals é versionada como qualquer arquivo de texto, você pode ter valores diferentes para -r para cada revisão. Além disso, você está navegando na documentação antiga 1.0. As definições externas foram alteradas na 1.5 e a versão atual é 1.7. Veja: svnbook.red-bean.com/en/1.7/svn.advanced.externals.html
liori
6

Separado!

Na verdade, eu provavelmente teria três repositórios, um para o cliente e as bibliotecas somente para clientes correspondentes, um para o servidor (e as bibliotecas correspondentes) e um para as bibliotecas compartilhadas (incorporando as interfaces API que expõem a funcionalidade entre os dois , além de qualquer outro código compartilhado). Eu acho que essa é realmente a chave, o código compartilhado deve entrar em um repositório separado. Dessa forma, você pode garantir que a interoperabilidade entre seu cliente e servidor esteja sempre na mesma versão E seja isolada do design de cada um de seus consumidores.

Obviamente, isso nem sempre é possível, dependendo da estrutura de comunicação específica que você está usando, mas é provável que haja um código compartilhado que dite o formato dos objetos de transferência de dados ou as etapas do handshake no seu protocolo personalizado (ou outro exemplo) .

Supondo que você tenha uma configuração de Integração Contínua e controle de qualidade razoavelmente decente (uma suposição bastante grande, na minha experiência, mas ainda vou fazer. Se você não tem um departamento de controle de qualidade, pelo menos deve obter um IC), deve não é necessário usar o padrão de repositório único como uma defesa contra possíveis correspondências incorretas de código; o servidor de IC sinalizará a interoperabilidade da biblioteca ou a equipe de controle de qualidade detectará erros de tempo de execução (ou, melhor ainda, os testes de unidade).

Os benefícios dos repositórios divididos estão na capacidade de versão separada de partes separadas de um sistema. Deseja tirar uma cópia do servidor da semana passada e executá-la com o cliente desta semana, para tentar bloquear a raiz de um problema de desempenho? Não se preocupe.

Ed James
fonte
1

No Mercurial , esse esquema pode ser usado, ->para indicar o relacionamento subrepo:

product -> client -|-> (many components)
                   |->  shared component A

        -> server -|-> (many components)
                   |->  shared component A

O produto tem subrepostos cliente, servidor. Cada um deles tem seus componentes como sub-repositórios, possivelmente pelo menos um sub-repositório compartilhado entre os dois.

A marcação provavelmente deve ser feita nos dois primeiros níveis, não abaixo disso.

As confirmações são feitas no nível do componente; os superrepostos efetivamente rastreiam ramificações e versões nomeadas do produto. Ramificações / marcadores nomeados geralmente são melhores que ramificações clonadas para usabilidade (por exemplo, capacidade de treinamento) e compatibilidade com subrepostos.

hg tende à suposição de que superrepos são o produto e as confirmações são feitas no nível superior, mas isso não funciona particularmente bem quando vários produtos usam os mesmos componentes. :-)

Não acho que esse esquema mude muito se for transferido para o git, mas ainda não o testei no git.

Paul Nathan
fonte
1

Este é um problema de gerenciamento de configuração, não um problema de controle de revisão. Como sempre, um programador usando uma chave de fenda para martelar um prego. Descubra como você gerenciará suas configurações, o controle de revisão cuidará de si mesmo.

mattnz
fonte
1

A abordagem mais simples é usar um único repositório; portanto, a menos que você goste da complexidade por causa da complexidade, essa deve ser a opção padrão na ausência de argumentos convincentes.

O desenvolvimento de clientes e servidores será realizado por diferentes organizações? Haverá várias implementações do cliente (ou servidor)? O código-fonte aberto do cliente e a implementação do servidor são secretos? Se a resposta para todas essas perguntas for "Não", qualquer coisa mais complexa do que um único repositório provavelmente trará apenas inconveniência sem nenhum benefício.

Se você optar por manter bases de código separadas, precisará de políticas claras sobre como isso é administrado, a fim de evitar incompatibilidades e dependência. Depois de trabalhar com os primeiros soluços, você pode acabar descobrindo que o mais seguro é sempre verificar os dois repositórios juntos, construí-los e implantá-los juntos ... o que obviamente derrota todo o propósito de separá-los!

A modularidade é uma propriedade agradável de se ter, mas a divisão de repositórios não é uma ferramenta para conseguir isso. Como o parágrafo anterior indica, você pode ter componentes altamente acoplados que são divididos em várias bases de código (indesejáveis) e da mesma forma que você pode ter componentes altamente modulares dentro da mesma base de código (desejável).

Em mais de uma ocasião, defendi (com sucesso) que minha equipe mesclasse repositórios git existentes, porque isso simplificou o desenvolvimento e a implantação.

Todd Owen
fonte
0

Esqueça o repositório por um momento. Como você organizaria os dois projetos em sua máquina se não estivesse compartilhando com ninguém? Como o resto da equipe faria isso? Você iria...

  • Coloque todos os arquivos de origem do cliente e do servidor no mesmo diretório?

  • Criar um diretório principal do projeto que contenha subdiretórios para o cliente e o servidor?

  • Manter os dois projetos completamente separados?

Depois de chegar a um consenso sobre isso como uma equipe, você está pronto para verificar os projetos no seu repositório de códigos. Todas as ferramentas de controle de revisão em que posso pensar estão felizes em reproduzir qualquer estrutura de diretório que você desejar - elas não se importam nem um pouco com qual arquivo pertence a qual projeto. E a diferença entre ter um repositório ou dois (ou seis) geralmente não é tão grande, além de pequenas diferenças administrativas.

Por exemplo, com o Subversion, a maior diferença entre repositórios separados para cliente e servidor e um único repositório combinado está na maneira como os números de revisão mudam. Com um repositório singe, o número da versão aumentará toda vez que você confirmar o código no cliente ou no servidor. Com repositórios separados, uma confirmação no projeto do servidor não altera o número da revisão principal do cliente.

Caleb
fonte