Eu sou outro usuário do Subversion lutando para me reeducar no Tao do controle de versão distribuído.
Ao usar o Subversion, eu era um grande fã da abordagem de projeto menor e, com a maioria dos meus ex-empregadores, estruturamos nossas ramificações de repositório; tags e tronco da seguinte forma:
branches-+
+-personal-+
| +-alice-+
| | +-shinyNewFeature
| | +-AUTOMATED-+
| | +-shinyNewFeature
| +-bob-+
| +-AUTOMATED-+
| +-bespokeCustomerProject
+-project-+
+-shinyNewFeature
+-fixStinkyBug
tags-+
+-m20110401_releaseCandidate_0_1
+-m20110505_release_0_1
+-m20110602_milestone
trunk
Dentro da própria árvore de origem, usaríamos (algo como) a seguinte estrutura:
(src)-+
+-developmentAutomation-+
| +-testAutomation
| +-deploymentAutomation
| +-docGeneration
| +-staticAnalysis
| +-systemTest
| +-performanceMeasurement
| +-configurationManagement
| +-utilities
+-libraries-+
| +-log-+
| | +-build
| | +-doc
| | +-test
| +-statistics-+
| | +-build
| | +-doc
| | +-test
| +-charting-+
| | +-build
| | +-doc
| | +-test
| +-distributedComputing-+
| | +-build
| | +-doc
| | +-test
| +-widgets-+
| +-build
| +-doc
| +-test
+-productLines-+
| +-flagshipProduct-+
| | +-coolFeature
| | +-anotherCoolFeature
| | +-build
| | +-doc
| | +-test
| +-coolNewProduct
+-project-+
+-bigImportantCustomer-+
| +-bespokeProjectOne
| +-bespokeProjectTwo
+-anotherImportantCustomer-+
+-anotherBespokeProject
A idéia era (e ainda é) usar a estrutura do repositório para ajudar a estruturar a comunicação entre a equipe de engenharia; a parte do negócio voltada para o cliente e vários outros interessados e especialistas em domínio.
A saber: os documentos de origem que estão em um dos diretórios "projeto" são usados (e ganham dinheiro) apenas uma vez. Os documentos que estão em um dos diretórios "productLines" ganham dinheiro quantas vezes um produto dessa linha específica é vendido. Os documentos que ficam em um dos diretórios de "bibliotecas" ganham dinheiro tantas vezes quanto os produtos que os utilizam são vendidos.
Isso torna explícita a noção de amortização de custos e ajuda a criar suporte para a reutilização de documentos de origem nos negócios.
Isso também significa que existe uma estrutura comum sobre a qual nossas ferramentas de automação de construção podem operar. (Nossos scripts de construção percorrem a árvore de origem procurando por pastas "construídas", nas quais eles encontram arquivos de configuração que especificam como cada componente deve ser construído; um processo semelhante ocorre para geração e teste de documentação).
Significativamente, os produtos nos quais trabalho normalmente levam muito tempo para executar testes de medição e caracterização de desempenho; de 20 a 200 horas; gerar algo entre vários GB e vários TB de resultados de testes processados / dados intermediários (que devem ser armazenados e vinculados a uma configuração específica do sistema para que a melhoria de desempenho ao longo do tempo possa ser medida). Esse problema torna o gerenciamento de configuração uma consideração importante e também impõe alguns requisitos para centralização, pois geralmente os recursos computacionais necessários para executar os testes de medição e caracterização de desempenho são limitados; (um pequeno cluster de 64 a 128 núcleos).
Como uma nota final; o sistema de integração contínua sabe que precisa acionar uma compilação; análise estática; teste de fumaça e teste de unidade sempre que o tronco é modificado, toda vez que qualquer ramificação "tag" é modificada e cada vez que qualquer ramificação "AUTOMATIZADA" é modificada. Dessa forma, desenvolvedores individuais podem usar o sistema de IC com suas ramificações pessoais, um recurso importante, o IMHO.
Agora, aqui está a minha pergunta: como posso replicar todas as opções acima (e melhorar, se possível) com o Mercurial.
--editar:
Minha linha de pensamento atual é usar um repositório central do Subversion, para definir a estrutura geral, mas permitir o uso do hg como um cliente para que os desenvolvedores possam ter repositórios disponíveis localmente.
fonte
Respostas:
A resposta de Spoike é excelente, mas acho que vale a pena acrescentar algumas coisas que são grandes demais para comentários.
Organização da filial
Com o Mercurial, você pode felizmente ignorar todo o seu primeiro organograma. Como diz o Spoke, cada repositório possui seu próprio conjunto de tags, ramificações (nomeadas e anônimas) e pode ser organizado de acordo com a necessidade do negócio.
Se
bespokeProjectTwo
precisar de uma versão especial docharting
biblioteca, você deverá ramificarcharting
, adicionar os novos recursos e usá-lobespokeProjectTwo
. As novas instalações (e seus bugs) não seriam usadas por outros projetos que fizessem referência àcharting
biblioteca padrão . Se acharting
biblioteca principal tiver bugs corrigidos, você poderá mesclar essas alterações na ramificação. Se outros projetos também precisassem dessas instalações, você poderia obter esses projetos para usar a ramificação especial ou mesclar a ramificação na linha principal e fechá-la.Além disso, nada impede que você tenha uma política para estruturar nomes de filiais para fornecer recursos específicos, como suas filiais de AUTOMATION.
Organização do diretório
Não há razão para que você não possa manter seu diretório de origem exatamente como no Mercurial. A única diferença é que enquanto no Subversion você tem um único monolítico
(src)
repositório , no Mercurial é melhor dividir em repositórios que são agrupados logicamente. Da estrutura da árvore de origem, provavelmente extrairia cada um dos seguintes como repositórios individuais:Isso permite que qualquer produto ou projeto sob medida use qualquer combinação de bibliotecas, em qualquer revisão. Dê uma olhada nos sub-repositórios mercuriais para uma maneira fácil de gerenciar quais bibliotecas são usadas para qualquer versão de um produto ou projeto.
Fluxo de trabalho
Uma alternativa ao fluxo de trabalho sugerido por Spoike (o desenvolvedor recebe do repo abençoado, trabalha localmente, emite uma solicitação de recebimento e, finalmente, o integrador realiza essas alterações e as mescla) seria usar o sistema de integração contínua como intermediário.
Como antes, o desenvolvedor retira do repositório abençoado e trabalha localmente, mas, quando concluído, retira-o do repositório abençoado e se fundem antes de avançar para um repositório não abençoado. Quaisquer alterações no repositório não abençoado são revisadas (manual ou automaticamente) e movidas para o repositório abençoado somente se forem aprovadas.
Isso significa que o integrador aceitou ou rejeitou apenas uma alteração, não faz a mesclagem. Na minha experiência, é quase sempre melhor para o desenvolvedor que escreveu o código executar a mesclagem do que para outra pessoa.
Conforme sugerido no livro mercurial, ganchos podem ser usados para automatizar este procedimento:
Outros problemas
O problema de grandes conjuntos de dados de teste também pode ser resolvido colocando esses dados em um sub-repositório mercurial . Isso impedirá que o repositório de código fique cheio de dados de teste, mantendo os dados de teste sob controle de revisão.
fonte
productLines
oubigImportantCustomer
como super-repositórios.Ok, tentando responder a isso simplesmente.
O que você precisa saber
Primeira coisa que você precisa saber: O Mercurial é um controle de versão distribuído e possui algumas propriedades que você deve conhecer listadas abaixo.
O modelo usual com o qual as pessoas trabalham no DVCS (que é empregado no github e no bitbucket) é fazê-lo semi-centralizado.
Cada usuário possui um repositório público (em algum compartilhamento ou em um servidor seguro) e um repositório privado (em suas próprias estações de trabalho). Ambos são clones do repositório "abençoado" de um integrador. Sempre que acharem que estão prontos para publicar seu código, poderão enviar as alterações para o repositório público. Um integrador pode então escolher quais usuários inserir código no repositório "abençoado".
Se o integrador não puder mesclar o código de algum usuário facilmente, as alterações serão rejeitadas e cabe a esse usuário específico atualizar seu repositório e corrigir a mesclagem. Geralmente, não é tão difícil se você mesclar com frequência (pois é menos código que precisa ser mesclado) e geralmente esse usuário deve saber o que deu errado com a mesclagem.
Configuração de repositórios por projeto
Portanto, a configuração usual é que, para cada projeto, exista o seguinte:
Um repositório público somente leitura pelo qual o integrador é responsável. É "abençoado".
Ou seja, todos os usuários podem obter / buscar conteúdo, mas não têm acesso para enviá-lo.
Cada usuário pode ter seu próprio clone público do repositório.
A configuração mais fácil é colocar em uma unidade de compartilhamento (embora você possa considerar a hospedagem como o bitbucket). O integrador recebe solicitações de recebimento dos usuários e tenta extrair o novo código desses repositórios. Quando as mesclagens são feitas sem problemas, elas são colocadas no repositório somente leitura. Caso contrário, os usuários são solicitados a corrigir os conflitos de mesclagem que surgem atualizando e mesclando-os localmente.
Cada usuário pode ter seus próprios clones particulares do repositório.
A boa prática é extrair do clone público, mas não importa se eles extraem do público ou do integrador. Todas as confirmações são identificáveis de forma exclusiva, portanto, a fusão das confirmações que você esqueceu de buscar no público é relativamente fácil de corrigir (empurrando as alterações do privado para o público, ele obtém automaticamente as alterações do integrador).
Organização do código fonte
Como em como organizar a própria fonte do projeto, é algo que você precisa pensar. Se um artefato precisar ser controlado pela fonte, coloque-o no controle da fonte. Pessoalmente, não gosto da ideia de fazer check-in de artefatos feitos pela construção ou tempo de execução (devido ao alto risco de conflitos de mesclagem nesses tipos de artefatos), como binários ou arquivos de log.
Você também pode verificar a configuração, desde que facilite o andamento dos desenvolvedores e não atrapalhe a configuração de releases ou ambiente de produção / produção (como configurações de aplicativos / servidores da web). Isso leva à noção de que se a configuração que você dificulta seriamente os desenvolvedores a começarem dentro de cinco minutos após o check-out do código, ele precisa ser refatorado. Outro requisito é que deve ser muito difícil para os desenvolvedores atrapalharem o ambiente de lançamento ou produção / produção.
Você mencionou que possui dados de teste que precisam estar vinculados a alguma versão do código. Agora isso é um pouco mais complicado, porque sistemas DVCS como Mercurial e Git tendem a ficar lentos quando você faz check-in de dados ENORME. Na minha experiência, fica realmente insuportável após 5 GB de arquivos binários (sua milhagem pode variar, portanto, você deve testar como funciona para você). No entanto, eu recomendo que você coloque os dados gerados em seu próprio repositório e faça com que seu sistema de teste os marque adequadamente ao fazer o check-in (e / ou criar arquivos de texto para os mesmos fins de metadados).
Eu espero que isso tudo faça sentido. Comente abaixo se eu perdi alguns detalhes ou se algo precisar de mais explicações e vou tentar editar.
fonte