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?

A mistura deles provavelmente facilitará o rastreamento de mudanças correlacionadas e a manutenção de ramificações correlacionadas (ou seja, a evolução do protocolo), mas, por outro lado, tornará o desenvolvimento individual mais confuso ...

    
por mbq 20.12.2011 / 16:54
fonte

6 respostas

12

Se você estiver usando git ou mercurial , então você pode querer olhar para submódulos ou subrepositórios .

O cliente, o servidor e seus arquivos de interface estariam em seus próprios repositórios, mas estariam interligados em o nível super-repositório . Isso permitiria que você fizesse um checkout no nível superior e git ou hg verificaria o commit apropriado de cada um dos submódulos / subrepositórios.

Ao se comprometer apenas com o super-repositório quando o cliente e o servidor eram apropriados um ao outro, o super-repositório só lhe daria a opção de verificar um sistema em funcionamento - assim você nunca tentaria executar o novo cliente contra um servidor antigo ou vice-versa.

Submódulos / subrepositórios dão a você todas as vantagens de usar repositórios separados, junto com as vantagens de um único repositório monolítico, às custas de um pouco de complexidade extra.

Esta resposta não pretende defender git ou hg sobre outros SCMs, acontece apenas que eu apenas conheço estes SCMs bem o suficiente para saber que esta opção existe . Eu não entendo como o svn externals funciona, por exemplo.

    
por 20.12.2011 / 17:55
fonte
6

Separar!

Na verdade, eu provavelmente teria três repositórios, um para o cliente e bibliotecas somente cliente correspondentes, uma para o servidor (e bibliotecas correspondentes) e outra para as bibliotecas compartilhadas (incorporando as interfaces da API que expõem a funcionalidade entre os dois, mais qualquer outro código compartilhado). Eu acho que é 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 determine o formato dos objetos de transferência de dados ou as etapas de handshake no seu protocolo personalizado (ou alguns outro exemplo).

Assumindo que você tenha uma configuração de integração contínua e de QA razoavelmente decente (uma suposição bastante grande, na minha experiência, mas que eu ainda farei. Se você não tiver um departamento de QA, você deve pelo menos obter um IC ) você não precisa usar o padrão single-repo como defesa contra possíveis erros de codificação, seu servidor de CI exibirá interoperabilidade de biblioteca ou sua equipe de QA detectará erros de tempo de execução (ou, melhor ainda, seus Testes de Unidade) vai).

Os benefícios dos repositórios divididos residem na capacidade de separar separadamente partes separadas de um sistema. Quer fazer uma cópia do Servidor da semana passada e executá-lo com o Cliente desta semana, para tentar bloquear a raiz de um problema de desempenho? Não se preocupe.

    
por 20.12.2011 / 18:04
fonte
1

Em Mercurial , esse esquema pode ser usado, usando -> para denotar um relacionamento subrepo:

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

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

O produto tem sub-clientes, servidor. Cada um deles tem seus componentes como sub-repos, possivelmente pelo menos um subrepo 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 super-posicionamentos rastreiam efetivamente as ramificações e versões nomeadas do produto. As ramificações / marcadores nomeados são geralmente melhores do que as ramificações de clones para facilidade de uso (ou seja, treinabilidade) e compatibilidade com sub-reposições.

hg tende a supor que os super-objetos são o produto, e os commits são feitos no nível mais alto, mas isso não funciona muito bem quando vários produtos usam os mesmos componentes. : -)

Eu não acho que esse esquema vai mudar muito se for migrado para o git, mas ainda não testei no git.

    
por 20.12.2011 / 19:43
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ê irá gerenciar suas configurações, o controle de revisão cuidará de si mesmo.

    
por 21.12.2011 / 02:55
fonte
1

A abordagem mais simples é usar um único repositório, portanto, a menos que você goste de complexidade pelo bem da complexidade, essa deve ser a escolha 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 a todas essas perguntas for "Não", então qualquer coisa mais complexa que um único repositório provavelmente trará apenas inconveniência para nenhum benefício.

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

A modularidade é uma boa propriedade para ter, mas dividir repositórios não é uma ferramenta para conseguir isso. Como o parágrafo anterior sugere, você pode ter componentes altamente acoplados que são divididos em múltiplas bases de código (indesejáveis), e da mesma forma você pode ter componentes altamente modulares dentro da mesma base de código (desejável).

Em mais de uma ocasião, defendo (com êxito) para que minha equipe mescle os repositórios git existentes, porque simplificou o desenvolvimento e a implantação.

    
por 25.01.2015 / 07:48
fonte
0

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

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

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

  • Mantenha 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ódigo. Todas as ferramentas de controle de revisão que consigo imaginar ficam felizes em reproduzir qualquer estrutura de diretórios que você goste - elas não se importam nem um pouco sobre 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á no modo como os números de revisão mudam. Com um repositório único, o número da versão aumentará toda vez que você confirmar o código para o cliente ou servidor. Com repositórios separados, uma confirmação para o projeto do servidor não alterará o número da revisão principal para o cliente.

    
por 20.12.2011 / 19:58
fonte