Wednesday 7 March 2018

Estratégia de ramificação do subversion


Estratégia de ramificação de subversão
Uma das características dos sistemas de controle de versão é a capacidade de isolar as mudanças em uma linha separada de desenvolvimento. Esta linha é conhecida como uma filial. Os ramos costumam ser usados ​​para experimentar novos recursos sem perturbar a linha principal de desenvolvimento com erros e erros de compilação. Assim que o novo recurso é estável o suficiente, o ramo de desenvolvimento é mesclado novamente no ramo principal (tronco).
Outro recurso dos sistemas de controle de versão é a capacidade de marcar revisões específicas (por exemplo, uma versão de lançamento), para que você possa, a qualquer momento, recriar uma determinada construção ou ambiente. Esse processo é conhecido como marcação.
O Subversion não possui comandos especiais para ramificação ou marcação, mas usa assim chamadas "cópias baratas". As cópias baratas são semelhantes aos links rígidos no Unix, o que significa que, em vez de fazer uma cópia completa no repositório, é criado um link interno, apontando para uma árvore / revisão específica. Como resultado, as ramificações e tags são muito rápidas de criar e quase não ocupam espaço extra no repositório.
Criando um ramo ou uma etiqueta.
Se você importou seu projeto com a estrutura de diretório recomendada, criar uma versão de ramo ou tag é muito simples:
Figura 4.52. A caixa de diálogo Branch / Tag.
Selecione a pasta na sua cópia de trabalho que deseja copiar para uma ramificação ou uma etiqueta e selecione o comando TortoiseSVN → Branch / Tag. .
O URL de destino padrão para o novo ramo será o URL de origem no qual a sua cópia de trabalho se baseia. Você precisará editar esse URL para o novo caminho da sua filial / tag. Então, ao invés de.
agora você pode usar algo como.
Se você não conseguir lembrar a convenção de nomenclatura usada na última vez, clique no botão à direita para abrir o navegador do repositório para poder visualizar a estrutura do repositório existente.
pastas intermediárias.
Quando você especifica o URL de destino, todas as pastas até o último já devem existir ou você receberá uma mensagem de erro. No exemplo acima, o URL svn. collab / repos / ProjectName / tags / deve existir para criar a marca Release_1.10.
No entanto, se você quiser criar uma ramificação / tag para uma URL que tenha pastas intermediárias que ainda não existem, marque a opção Criar pastas intermediárias na parte inferior da caixa de diálogo. Se essa opção estiver ativada, todas as pastas intermediárias serão criadas automaticamente.
Observe que esta opção está desativada por padrão para evitar erros de digitação. Por exemplo, se você digitar o URL de destino como svn. collab / repos / NomeProjeto / Tags / Release_1.10 em vez de svn. collab / repos / NomeDoProjeto / tags / Release_1.10, você receberá um erro com a opção desabilitada, mas com a opção habilitada uma pasta, as tags seriam criadas automaticamente e você terminaria com uma pasta Tags e uma etiqueta de pasta.
Agora você deve selecionar a fonte da cópia. Aqui você tem três opções:
O novo ramo é copiado diretamente no repositório da revisão HEAD. Nenhum dado precisa ser transferido da sua cópia de trabalho, e o ramo é criado muito rapidamente.
Revisão específica no repositório.
O novo ramo é copiado diretamente no repositório, mas você pode escolher uma revisão mais antiga. Isso é útil se você esqueceu de fazer uma marca quando você lançou seu projeto na semana passada. Se não conseguir lembrar o número de revisão, clique no botão à direita para mostrar o registro de revisão e selecione o número de revisão a partir dele. Novamente, nenhum dado é transferido da sua cópia de trabalho, e o ramo é criado muito rapidamente.
A nova ramificação é uma cópia idêntica da sua cópia de trabalho local. Se você atualizou alguns arquivos para uma revisão mais antiga em seu WC, ou se você fez alterações locais, é exatamente isso que entra na cópia. Naturalmente, esse tipo de tag complexo pode envolver a transferência de dados do seu WC de volta para o repositório, se ele ainda não existir.
Se desejar que a sua cópia de trabalho seja alterada automaticamente para o ramo recém-criado, use a opção Trocar a cópia de trabalho para novas filiais / tags. Mas se você fizer isso, primeiro certifique-se de que sua cópia de trabalho não contenha modificações. Se o fizer, essas alterações serão incorporadas no branch WC quando você alternar.
Se a sua cópia de trabalho tiver outros projetos incluídos com svn: propriedades externas, esses externos serão listados na parte inferior da caixa de diálogo de ramificação / tag. Para cada externo, o caminho de destino e o URL de origem são mostrados.
Se você quiser ter certeza de que a nova tag está sempre em um estado consistente, verifique todas as externas para ter suas revisões marcadas. Se você não verificar os externos e esses externos apontam para uma revisão HEAD que pode mudar no futuro, verificar a nova etiqueta verificará se a revisão HEAD do externo e sua tag podem não compilar mais. Portanto, é sempre uma boa idéia configurar os externos para uma revisão explícita ao criar uma tag.
Os externos são automaticamente fixados na revisão HEAD atual ou na revisão BASE da cópia de trabalho, dependendo da fonte do ramo / tag:
Tabela 4.1. Revisão fixada.
externos dentro dos externos.
Se um projeto que está incluído como externo, ele próprio incluiu externos, então esses não serão marcados! Somente elementos externos que são filhos diretos podem ser marcados.
Pressione OK para confirmar a nova cópia no repositório. Não esqueça de fornecer uma mensagem de log. Observe que a cópia é criada dentro do repositório.
Observe que, a menos que você tenha optado por trocar sua cópia de trabalho para a ramificação recém-criada, a criação de uma Filial ou Tag não afetará sua cópia de trabalho. Mesmo que você crie o ramo do seu WC, essas alterações estão comprometidas com o novo ramo, não com o tronco, de modo que seu banheiro ainda pode ser marcado como modificado em relação ao tronco.
Outras maneiras de criar uma ramificação ou tag.
Você também pode criar uma ramificação ou tag sem ter uma cópia de trabalho. Para fazer isso, abra o navegador do repositório. Você pode arrastar pastas para um novo local. Você tem que manter pressionada a tecla Ctrl enquanto arrasta para criar uma cópia, caso contrário a pasta será movida, não copiada.
Você também pode arrastar uma pasta com o botão direito do mouse. Depois de soltar o botão do mouse, você pode escolher no menu de contexto se deseja que a pasta seja movida ou copiada. Claro que para criar um ramo ou uma etiqueta, você deve copiar a pasta, não movê-la.
Mais uma vez é a partir do diálogo de log. Você pode mostrar a caixa de diálogo de log para e. tronco, selecione uma revisão (seja a revisão HEAD no topo ou uma revisão anterior), clique com o botão direito do mouse e escolha criar ramificação / etiqueta de revisão. .
Para efetuar o checkout ou mudar.
. Isso é (não realmente) a questão. Enquanto um checkout faz o download de tudo, desde o ramo desejado no repositório até o seu diretório de trabalho, o TortoiseSVN → Switch. apenas transfere os dados alterados para a sua cópia de trabalho. Bom para a carga da rede, bom para sua paciência. :-)
Para poder trabalhar com seu ramo ou tag recentemente gerado, você tem várias maneiras de lidar com isso. Você pode:
TortoiseSVN → Checkout para fazer um novo checkout em uma pasta vazia. Você pode fazer check-out em qualquer local em seu disco local e pode criar quantas cópias de trabalho do seu repositório desejar.
Mude sua cópia de trabalho atual para a cópia recém-criada no repositório. Selecione novamente a pasta de nível superior do seu projeto e use TortoiseSVN → Switch. no menu de contexto.
Na próxima caixa de diálogo, insira o URL do ramo que você acabou de criar. Selecione o botão de opção Revisão principal e clique em OK. Sua cópia de trabalho é alterada para o novo branch / tag.
Switch funciona como Update, na medida em que nunca descarta as mudanças locais. Todas as alterações que você fez na sua cópia de trabalho que ainda não foram cometidas serão mescladas quando você fizer o Switch. Se não quiser que isso aconteça, você deve confirmar as alterações antes de alternar ou reverter sua cópia de trabalho para uma revisão já confirmada (normalmente, HEAD).
Se você quiser trabalhar no tronco e no ramo, mas não quer a despesa de uma nova compra, você pode usar o Windows Explorer para fazer uma cópia da sua caixa de entrada no tronco em outra pasta, então TortoiseSVN → Alternar. Essa cópia para sua nova filial.
Figura 4.53. O diálogo de troca.
Embora o próprio Subversion não faça distinção entre tags e branches, o modo como eles são tipicamente usados ​​difere um pouco.
As tags normalmente são usadas para criar um instantâneo estático do projeto em uma determinada etapa. Como tal, eles normalmente não são usados ​​para o desenvolvimento - é por isso que os ramos são para, o que é o motivo pelo qual recomendamos a estrutura do repositório / tronco / ramos / tags em primeiro lugar. Trabalhar em uma revisão de tag não é uma boa idéia, mas porque seus arquivos locais não são protegidos contra gravação, não há nada para impedir que você faça isso por engano. No entanto, se você tentar se comprometer com um caminho no repositório que contém / tags /, o TortoiseSVN irá avisá-lo.
Pode ser que você precise fazer mais alterações em um release que já tenha marcado. A maneira correta de lidar com isso é criar um novo ramo da tag primeiro e confirmar o ramo. Faça suas alterações neste ramo e, em seguida, crie uma nova tag desse novo ramo, p. Ex. Versão_1.0.1.
Se você modificar uma cópia de trabalho criada a partir de uma ramificação e confirmação, todas as alterações vão para a nova ramificação e não para o tronco. Somente as modificações são armazenadas. O resto continua sendo uma cópia barata.

Estratégia de ramificação de subversão
Se você não "rebase" (Fig. A), você acabará entregando todo o conjunto de alterações toda vez e mesclará efetivamente as alterações que já foram mescladas. Mas se você fizer o rebase (Fig. B) - que é fundir tronco para o ramo de desenvolvimento imidiately, então a subversão é capaz de saber a diferença.
svn switch svn: // servidor / trunk svn: // servidor / branches / trunk / dev1.
Faça isso e cometer isso.
svn commit - m "Adicionado um diretório b"
Volte para o tronco e puxe as mudanças do ramo dev.
svn merge svn: // servidor / trunk svn: // servidor / ramificações / trunk / dev1.
svn commit - m "empurrou dev1 para o tronco"
Agora volte a continuar o trabalho no ramo de desenvolvimento.
Aí vem a solução muito importante para o desconhecimento do ramo de desenvolvimento sobre o que aconteceu. Você simplesmente combina o tronco no ramo de desenvolvimento antes de continuar trabalhando.
E agora é seguro continuar usando o ramo de desenvolvimento - como você faria no git, Mercurial ou ClearCase.

Estratégia de ramificação do Subversion
Obter através da App Store Leia esta publicação em nosso aplicativo!
Estratégias de ramificação [fechado]
A empresa para a qual trabalho está começando a ter problemas com seu atual modelo de ramificação e fiquei me perguntando para quais diferentes tipos de estratégias de ramificação a comunidade foi exposta?
Há algum bom para situações diferentes? O que a sua empresa usa? Quais são as vantagens e desvantagens deles?
fechado como não construtivo por casperOne Fev 24 '12 às 19:53.
Como está atualmente, esta questão não é uma boa opção para o nosso formato Q & amp; A. Esperamos que as respostas sejam apoiadas por fatos, referências ou conhecimentos, mas esta questão provavelmente solicitará debate, argumentos, votação ou discussão prolongada. Se achar que esta questão pode ser melhorada e possivelmente reaberta, visite o centro de ajuda para obter orientação. Se esta questão pode ser reformulada para ajustar as regras no centro de ajuda, edite a questão.
17 Respostas.
Aqui está o método que usei no passado com bom sucesso:
/ tronco - borda sangrenta. Próximo lançamento principal do código. Pode ou não funcionar em qualquer momento.
/branches/1.0, 1.1, etc. Ramos de manutenção estáveis ​​do código. Usado para corrigir erros, estabilizar novos lançamentos. Se um ramo de manutenção, ele deve compilar (se aplicável) e estar pronto para QA / envio em qualquer momento. Se um ramo de estabilização, ele deve compilar e ser completo. Nenhum novo recurso deve ser adicionado, nenhuma refatoração e nenhuma limpeza de código. Você pode adicionar um pré-prefixo para indicar ramos de estabilização versus ramificações de manutenção.
/ branches / cool_feature. Usado para trabalhos altamente experimentais ou destrutivos que podem ou não entrar no tronco (ou um ramo de manutenção). Não há garantias sobre a compilação de código, o funcionamento ou de outra forma que se comporte de forma sanamente. Deve durar o mínimo de tempo possível antes de se fundir no ramo principal.
/tags/1.0.1, 1.0.2, 1.1.3a, etc. Usado para marcar um pacote & amp; lançamento enviado. Nunca muda sempre. Faça quantas tags quiser, mas elas são imutáveis.
Eu recomendo fortemente ler a opinião de Eric Sink sobre o assunto:
Eu, como Eric, prefiro o estilo de "pasta" que ele fala.
Para o filão mãe sobre padrões de ramificação, veja Linhas Transplantadas de Brad Appleton: Padrões de Ramificação para Desenvolvimento de Software Paralelo. É pesado, mas não vi nada para superá-lo em termos de amplitude e profundidade de conhecimento sobre ramificação.
Nosso repositório parece:
/ trunk é o seu desenvolvimento padrão e de ponta. Usamos o CI para que isso sempre seja feito e aprovado nos testes.
/ branches é onde nós colocamos grandes mudanças 'sancionadas', ou seja, algo que sabemos que irá transformá-lo em tronco, mas pode precisar de algum trabalho e quebrar CI. Também onde trabalhamos em lançamentos de manutenção, que possuem seus próprios projetos de CI.
/ sandbox cada desenvolvedor tem sua própria sandbox, além de uma sandbox compartilhada. Isto é para coisas como "Vamos adicionar um fornecedor LINQ ao nosso produto", tipo de tarefas que você faz quando você não está fazendo seu trabalho real. Pode eventualmente entrar no tronco, pode não ser, mas está lá e sob controle de versão. Não há CI aqui.
/ fornecedor fornecedor de ramo padrão para projetos onde nós compilamos, mas não é o código que mantemos.
/ ccnet são nossas tags de CI, somente o servidor de IC pode gravar aqui. Hindsight teria nos dito que renomeie isso para algo mais genérico, como CI, BUILDS, etc.
Uma ramificação para o desenvolvimento ativo (/ main ou master, dependendo do jargão) Um branch para cada release de manutenção -> ele receberá apenas pequenas correções, enquanto todo o desenvolvimento principal vai para / main Um branch para cada nova tarefa: criar um novo ramo para trabalhar em cada nova entrada no seu Bugzilla / Jira / Rally. Comprometa-se frequentemente, documente a alteração usando check-ins de seixos em polegadas e mescle-os de volta à sua ramificação "pai" apenas quando ela estiver concluída e bem testada.
A primeira coisa: KISS (Mantenha isso simples, estúpido!)
* 1) Manter a versão mantida - por ex. Service Packs, Hotfixes, correções de erros que podem ser mescladas ao tronco, se necessário e / ou necessário) * 2) major. minor. build. revision.
A pasta Tags não precisa ser verificada. Apenas poucas codificações nos ramos de lançamento (faz a fusão mais simples) - sem limpeza de código etc. Nunca para codificar na pasta de tags Nunca coloque informações de versão concretas em arquivos de origem. Use o Place-holder ou o 0.0.0.0 que o mecanismo de compilação irá substituir pelo número da versão que você está construindo. Nunca coloque bibliotecas de terceiros no seu controle de origem (também ninguém adicionará bibliotecas STL, MFC, etc. para SVN ;-)) Somente código de confirmação que compila Prefer usando variáveis ​​de ambiente em vez de caminhos codificados (caminhos absolutos e relativos)
Nós nos ramificamos quando uma versão está pronta para QA final. Se algum problema for descoberto durante o processo de QA, os erros são corrigidos no ramo, são validados e depois são mesclados no tronco. Depois que o branch passa no controle de qualidade, nós o etiquetamos como um lançamento. Quaisquer hotfixes para essa versão também são feitos para o ramo, validados, fundidos no tronco e depois marcados como uma versão separada.
A estrutura da pasta seria semelhante a esta (1 linha de controle de qualidade, 2 lançamentos de hotfix e o tronco):
Usamos o estilo selvagem, selvagem e ocidental dos ramos-git. Nós temos alguns ramos que conhecem nomes bem conhecidos definidos por convenção, mas, no nosso caso, as tags são realmente mais importantes para nós atender aos nossos requisitos de política de processo corporativo.
Eu vi abaixo que você usa o Subversion, então eu estou pensando que você provavelmente deve verificar a seção sobre ramificação no Livro do Subversion. Especificamente, veja a seção "layout do repositório" na Manutenção de filial e Padrões de ramo comum.
A alternativa que não estou vendo aqui é uma filosofia "Branch on Change".
Em vez de ter seu porta-malas, o "Oeste Selvagem", e se o porta-malas for o "Release Atual"? Isso funciona bem quando há apenas uma versão do aplicativo lançada por vez - como um site. Quando uma nova característica ou correção de bugs é necessária, um ramo é feito para manter essa mudança. Geralmente, isso permite que as correções sejam migradas para serem liberadas individualmente e impede que os codificadores de caubóis adicionem acidentalmente um recurso a ser lançado que você não pretendia. (Muitas vezes é um backdoor - "Apenas para desenvolvimento / teste")
Os ponteiros de Ben Collins são bastante úteis para determinar qual estilo funcionaria bem para sua situação.
O Controle de Versão de Henrik Kniberg para Múltiplas Equipes Ágeis também tem alguns pontos positivos a serem levados em consideração.
Atualmente, temos uma filial para manutenção contínua, um ramo para "novas iniciativas", que significa apenas "coisas que sairão em algum momento no futuro; não temos certeza de quando". Nós também temos ocasionalmente dois ramos de manutenção: um para fornecer correções para o que está atualmente em produção e um ainda em QA.
A principal vantagem que vimos é a capacidade de reagir às solicitações e emergências do usuário mais rapidamente. Podemos fazer a correção na ramificação que está em produção e liberá-la sem liberar nada extra que já tenha sido verificado.
A principal desvantagem é que acabamos fazendo muita fusão entre os ramos, o que aumenta a chance de que algo seja perdido ou fundiu incorretamente. Até agora, isso não tem sido um problema, mas é definitivamente algo para se ter em mente.
Antes de instituirmos esta política, geralmente fazíamos todo o desenvolvimento no tronco e apenas ramificávamos quando lançávamos o código. Em seguida, fizemos correções contra esse ramo, conforme necessário. Era mais simples, mas não tão flexível.
Jeff Atwood escreveu sobre isso em uma boa postagem no blog; Essa publicação tem alguns links importantes nele.
Gnat escreveu este excelente desdobramento nos vários pontos de aconselhamento que você pode encontrar em estratégias de ramificação.
Não há uma estratégia de ramificação, é para isso que funciona:
O tamanho da sua equipe Seu produto e os períodos do ciclo de vida A tecnologia que você está usando (aplicativos da Web, incorporados e do Windows) Seu controle de origem, por exemplo, Git, TFS, Hg.
O post de Jeff Atwood quebra muitas possibilidades. Outro para adicionar é o conceito de promoção (do link de Ryan Duffield). Nesta configuração, você possui um ramo de desenvolvimento, teste bracnh e ramo de lançamento. Você promove seu código até chegar ao ramo de lançamento e é implantado.
A filosofia que seguimos no trabalho é manter o tronco em um estado onde você pode empurrar a qualquer momento sem dano drástico ao site. Isso não quer dizer que o tronco esteja sempre em perfeito estado. Naturalmente, haverá erros nela. Mas o ponto é nunca, nunca deixá-lo quebrado drasticamente.
Se você tem um recurso para adicionar, ramo. Uma mudança de design, ramo. Houve tantas vezes em que pensei: "oh, eu posso fazer isso no tronco, não vai demorar tanto tempo", e depois 5 horas depois, quando não consigo descobrir o bug que está quebrando coisas, eu realmente desejei que eu tivesse ramificado.
Quando você mantém o tronco limpo, você permite a oportunidade de se aplicar rapidamente e afastar as correções de bugs. Você não precisa se preocupar com o código quebradiço que você possui, que você se separou convenientemente.
Isso dependeria de qual sistema de controle de versão você estiver usando. Cada VCS possui diferentes abordagens para ramificação.
Qual o VSC você usa?
Para o Subversion, eu concordo com o comentário de Ryan Duffield. O capítulo a que ele se refere fornece uma boa análise sobre qual sistema usar.
A razão pela qual eu perguntei é que a Perforce fornece uma maneira completamente diferente de criar filiais do SVN ou CVS. Além disso, existem todos os DVCS que dão sua própria filosofia em ramificação. Sua estratégia de ramificação seria ditada por qual ferramenta (s) você está usando.
FYI, Svnmerge. py é uma ferramenta para auxiliar na fusão de filiais no SVN. Ele funciona muito bem, desde que você o use com freqüência (a cada 10-30) commits, caso contrário a ferramenta pode ficar confusa.
Não importa qual padrão de ramificação escolhido, você deve tentar manter seus ramos em uma árvore binária como esta:
Os nós infantis devem apenas se fundir com o pai direto. Experimente o melhor para juntar apenas o ramo inteiro com o ramo pai. nunca junte subpastas dentro de um ramo. Você pode tentar a seleção de cereja quando necessário, desde que você apenas funda e escolha de todo o ramo. O próximo ramo na figura acima é apenas para ilustração, você pode não precisar disso.

Estratégia de ramificação de subversão
Obter através da App Store Leia esta publicação em nosso aplicativo!
Melhor estratégia de ramificação ao fazer integração contínua?
Qual é a melhor estratégia de ramificação a ser usada quando você deseja fazer integração contínua?
Release Branching: desenvolva no tronco, mantenha um ramo para cada lançamento. Ramificação de recursos: desenvolva cada recurso em uma ramificação separada, apenas funde uma vez estável.
Faz sentido usar essas duas estratégias juntas? Como em, você se ramifica para cada versão, mas você também se ramifica para grandes recursos? Uma dessas estratégias combina melhor com a integração contínua? Usar integração contínua ainda faz sentido ao usar um tronco instável?
11 Respostas.
A resposta depende do tamanho da sua equipe e da qualidade do seu controle de origem e da capacidade de mesclar conjuntos de mudanças complexas corretamente. Por exemplo, no controle de fonte de ramificação completa como CVS ou SVN, a fusão pode ser difícil e você pode estar melhor com o primeiro modelo, enquanto se estiver usando um sistema mais complexo como o IBM ClearCase e com um tamanho maior de equipe, modelo ou uma combinação dos dois.
Eu, pessoalmente, separaria o modelo de ramal de recursos, onde cada característica principal é desenvolvida em um ramo separado, com subdivisões de tarefas para cada mudança feita pelo desenvolvedor individual. À medida que os recursos se estabilizam, eles são mesclados ao tronco, que você mantém razoavelmente estável e passando em todos os testes de regressão o tempo todo. À medida que você se aproxima do final de seu ciclo de lançamento e todos os ramos de recursos se mesclam, você estabiliza e ramifica uma ramificação do sistema de lançamento na qual você só faz correções de bugs de estabilidade e backports necessários, enquanto o tronco é usado para desenvolvimento da próxima versão e você novamente se ramificam para novos ramos de recursos. E assim por diante.
Dessa forma, o trunk contém sempre o código mais recente, mas você consegue mantê-lo razoavelmente estável, criando rótulos estáveis ​​(tags) em grandes mudanças e mesclagens de recursos, os ramos de recursos são desenvolvimento rápido com integração contínua e sub-ramificações de tarefas individuais atualizado a partir do ramo de recursos para manter todos trabalhando no mesmo recurso em sincronia, sem afetar outras equipes que trabalham em diferentes recursos.
Ao mesmo tempo, você tem através do histórico um conjunto de ramos de lançamento, onde você pode fornecer backports, suporte e correções de erros para seus clientes que, por qualquer motivo, permanecem em versões anteriores do seu produto ou mesmo apenas na versão mais recente lançada. Tal como acontece com o tronco, você não configura a integração contínua nos ramos de lançamento, eles são cuidadosamente integrados ao passar todos os testes de regressão e outros controles de qualidade de liberação.
Se por algum motivo dois recursos são co-dependentes e precisam de mudanças feitas um com o outro, você pode considerar desenvolver ambos no mesmo ramo de recursos ou exigir que os recursos agrupem regularmente partes estáveis ​​do código no tronco e depois atualize as alterações de tronco para trocar código entre ramos do tronco. Ou, se você precisar isolar esses dois recursos de outras pessoas, poderá criar uma ramificação comum na qual ramificará essas ramificações de recursos e poderá usá-las para trocar códigos entre os recursos.
O modelo acima não faz muito sentido com equipes com menos de 50 desenvolvedores e sistema de controle de fonte sem ramos esparsos e capacidade de fusão adequada como CVS ou SVN, o que tornaria todo esse modelo um pesadelo para configurar, gerenciar e integrar.
Eu acho o tópico realmente interessante, porque eu confio muito nas filiais no meu trabalho diário.
Lembro-me de Mark Shuttleworth propondo um modelo sobre manter o ramo principal intocado, indo além do IC convencional. Eu postei sobre isso aqui. Como estou familiarizado com o Cruise Control, também bloguei sobre filiais de tarefas e CI aqui. É um tutorial passo a passo explicando como fazê-lo com SCM de plástico. Finalmente, encontrei alguns dos tópicos sobre CI (e potencialmente falando sobre ramificação) no livro de Duvall sobre CI muito interessante também.
Espero que você ache os links interessantes.
Eu pessoalmente acho muito mais limpo ter um tronco estável e apresentar ramificações. Dessa forma, os testadores e similares conseguem permanecer em uma única "versão" e atualizar do tronco para testar qualquer recurso que seja codificado.
Além disso, se vários desenvolvedores estiverem trabalhando em recursos diferentes, eles podem ter seus próprios ramos separados, depois fundir no tronco quando terminarem e enviar um recurso para serem testados sem que o testador tenha que alternar para vários ramos para testar diferentes recursos.
Como um bônus adicional, há algum nível de testes de integração que vem automaticamente.
Penso que qualquer uma das estratégias pode ser usada com o desenvolvimento contínuo, desde que você se lembre de um dos princípios fundamentais que cada desenvolvedor comete no tronco / mainline todos os dias.
Eu tenho feito algumas leituras deste livro sobre CI e os autores sugerem que a ramificação por lançamento é a estratégia de ramificação preferida. Eu tenho que concordar. A ramificação por recurso não faz sentido para mim ao usar o IC.
Vou tentar e explicar por que estou pensando dessa maneira. Digamos que três desenvolvedores tomem um ramo para trabalhar em um recurso. Cada recurso levará vários dias ou semanas para ser concluído. Para garantir que a equipe esteja se integrando continuamente, eles devem se comprometer com a filial principal pelo menos uma vez por dia. Assim que começam a fazer isso, perdem o benefício de criar um branch de recursos. Suas mudanças não estão mais separadas de todas as outras mudanças do desenvolvedor. Sendo esse o caso, por que se preocupar em criar branches em primeiro lugar?
O uso de ramificação por versão requer muito menos fusão entre os ramos (sempre é uma coisa boa), garante que todas as alterações sejam integradas o mais rápido possível e (se feito corretamente) garante que sua base de código esteja sempre pronta para ser liberada. O lado negativo para se ramificar pelo lançamento é que você deve ter um cuidado consideravelmente mais cuidadoso com as mudanças. Por exemplo. A refatoração ampla deve ser feita de forma incremental e, se você já integrou um novo recurso que não deseja na próxima versão, ele deve estar oculto usando algum tipo de mecanismo de alternância de recursos.
Há mais de uma opinião sobre este assunto. Aqui está uma postagem no blog que é pro feature branching with CI.
Os ramos de lançamento são muito úteis, e até mesmo absolutamente necessários, se você precisar manter várias versões do seu aplicativo.
Os ramos de recursos também são muito convenientes, especialmente se um desenvolvedor precisa trabalhar em uma grande mudança, enquanto outros ainda lançam novas versões.
Então, para mim, usar ambos os mecanismos é uma estratégia muito boa.
Link interessante do Livro do SVN.
Eu recentemente cheguei a gostar deste modelo ao usar o git. Embora sua pergunta seja marcada como "svn", você ainda pode fazer algum uso disso.
A integração contínua pode, em certa medida, acontecer no ramo "desenvolver" (ou seja o que for que você chamar) neste modelo, embora possuir ramos de recursos longos para lançamentos futuros não o tornem tão rígido quanto a considerar cada mudança acontecendo com o código em algum lugar. A questão permanece, se você realmente quer isso. Martin Fowler faz.
A integração contínua não deve ser qualquer tipo de fator na determinação de sua estratégia de ramificação. Sua abordagem de ramificação deve ser selecionada com base em sua equipe, no sistema em desenvolvimento e nas ferramentas disponíveis para você.
Tendo dito isto .
não há nenhuma razão para que a CI não possa ser usada em ambas as abordagens que você descreve, essas abordagens funcionam bastante bem em combinação, nenhum dos dois trabalha "melhor" do que o outro CI faz todo o sentido com um tronco instável.
Tudo isso foi respondido na quarta pergunta na página da qual você tirou os diagramas: blogs. collab / subversion / 2007/11 / branching-strat /
Contanto que você entenda os princípios, você sempre pode reinventar as melhores práticas. Se você não entender os princípios, as melhores práticas irão levá-lo até antes de desmoronar devido a algum requisito externo conflitante.
Leia o link. Uma vez que você obteve o básico, leia o seguinte artigo pelo venerável Henrik Kniberg. Ele irá ajudá-lo a relacionar o Mainline Model com integração contínua.
Quando iniciamos nossa equipe, herdamos uma estratégia baseada em lançamentos do fornecedor que originalmente desenvolveu o sistema ao qual estávamos prestes a se encarregar. Funcionou até o momento em que nossos clientes solicitaram que vários recursos desenvolvidos não fossem incluídos em uma versão (f. y.i.
250k linhas de código,
2500 arquivos, Scrum com XP SDLC).
Em seguida, começamos a olhar para os ramos baseados em recursos. Isso também funcionou por um tempo - como 2 meses até o momento em que percebemos que nosso processo de teste de regressão levaria mais de 2 semanas, o que combinado com a incerteza do que seria lançado criou uma enorme inconveniência.
O último "prego no caixão" de estratégias SC puras veio quando decidimos que deveríamos ter 1. tronco estável e 2. A produção deveria conter BINÁRIOS testados ST, UAT e Regressão (não apenas fonte - pense CC).
Isso nos levou a elaborar uma estratégia que é um híbrido entre as estratégias de SC baseadas em recursos e em releases.
Então nós temos um baú. Em cada sprint, nós ramificamos o ramo de sprint (para o pessoal não ágil - um sprint é apenas um esforço de desenvolvimento com saída variável baseado na complexidade). A partir do ramo de sprint, criamos os ramos de recursos e o desenvolvimento paralelo é iniciado neles. Uma vez que os recursos estão completos e testados pelo sistema, e recebemos a intenção de implementá-los, eles são incorporados ao ramo de sprint - alguns podem flutuar em vários sprints, geralmente os mais complexos. Quando o sprint estiver próximo do final e os recursos estiverem completos. nós "renomeamos" o ramo de sprint para "regressão" (isso permite que o CruiseControl o apanhe sem qualquer reconfiguração) e o teste de regressão / integração começa no EAR construído no cc. Quando tudo estiver pronto, ele vai em produção.
Em suma, os ramos baseados em recursos são usados ​​para desenvolver, teste do sistema e funcionalidade UAT. O ramo de sprint (realmente o ramo de lançamento) é usado para mesclar seletivamente os recursos sob demanda e teste de integração.
Agora, aqui é uma questão para a comunidade - obviamente estamos tendo problemas para realizar uma integração contínua devido ao fato de que o desenvolvimento acontece em muitos ramos e a sobrecarga de reconfiguração do CruiseControl. Alguém pode sugerir e aconselhar?
Do jeito que eu vejo você quer ter um conjunto limitado de ramos onde você pode se concentrar. Uma vez que você deseja testes, métricas de qualidade de código e muitas coisas interessantes para executar com as compilações, ter muitos relatórios provavelmente irá levá-lo a perder informações.
Quando e o que ramificar, geralmente depende do tamanho da equipe e do tamanho dos recursos que estão sendo desenvolvidos. Eu não acho que haja uma regra de ouro. Certifique-se de usar uma estratégia na qual você possa obter feedback com antecedência / frequência, e isso inclui ter a qualidade envolvida desde o início dos recursos. O bit de qualidade significa que, à medida que você está automatizando à medida que a equipe se desenvolve, se você se ramifica para um grande conjunto de recursos criado por uma equipe, você também deve ter qualidade envolvida na equipe.
ps Onde você obteve as referências da abordagem? - não acha que esses gráficos representam todas as opções.
Atualização 1: expandindo porque eu disse que não é uma regra de ouro. Basicamente, para equipes relativamente pequenas, achei melhor usar uma abordagem que seja uma mistura. Os ramos de recursos são criados se for algo longo e parte da equipe continuará adicionando recursos menores.
Eu acho que as ferramentas que você usa são um grande fator aqui.
Se você estiver usando a subversão, aderindo à opção 1 e soltando as filiais. Se você estiver usando o GIT, a opção 2 funcionará bem para você.

Estratégia de ramificação de subversão
Esta documentação foi escrita para descrever a série 1.7.x do Apacheв "ў Subversion®. If you are running a different version of Subversion, you are strongly encouraged to visit svnbook/ and instead consult the version of this documentation appropriate for your version of Subversion.
Common Branching Patterns.
There are many different uses for branching and svn merge , and this section describes the most common.
Version control is most often used for software development, so here's a quick peek at two of the most common branching/merging patterns used by teams of programmers. If you're not using Subversion for software development, feel free to skip this section. If you're a software developer using version control for the first time, pay close attention, as these patterns are often considered best practices by experienced folk. These processes aren't specific to Subversion; they're applicable to any version control system. Still, it may help to see them described in Subversion terms.
Release Branches.
Most software has a typical life cycle: code, test, release, repeat. There are two problems with this process. First, developers need to keep writing new features while quality assurance teams take time to test supposedly stable versions of the software. New work cannot halt while the software is tested. Second, the team almost always needs to support older, released versions of software; if a bug is discovered in the latest code, it most likely exists in released versions as well, and customers will want to get that bug fix without having to wait for a major new release.
Here's where version control can help. The typical procedure looks like this:
Developers commit all new work to the trunk. Day-to-day changes are committed to /trunk : new features, bug fixes, and so on.
The trunk is copied to a “ release ” branch. When the team thinks the software is ready for release (say, a 1.0 release), /trunk might be copied to /branches/1.0 .
Teams continue to work in parallel. One team begins rigorous testing of the release branch, while another team continues new work (say, for version 2.0) on /trunk . If bugs are discovered in either location, fixes are ported back and forth as necessary. At some point, however, even that process stops. The branch is “ frozen ” for final testing right before a release.
The branch is tagged and released. When testing is complete, /branches/1.0 is copied to /tags/1.0.0 as a reference snapshot. The tag is packaged and released to customers.
The branch is maintained over time. While work continues on /trunk for version 2.0, bug fixes continue to be ported from /trunk to /branches/1.0 . When enough bug fixes have accumulated, management may decide to do a 1.0.1 release: /branches/1.0 is copied to /tags/1.0.1 , and the tag is packaged and released.
This entire process repeats as the software matures: when the 2.0 work is complete, a new 2.0 release branch is created, tested, tagged, and eventually released. After some years, the repository ends up with a number of release branches in “ maintenance ” mode, and a number of tags representing final shipped versions.
Feature Branches.
A feature branch is the sort of branch that's been the dominant example in this chapter (the one you've been working on while Sally continues to work on /trunk ). It's a temporary branch created to work on a complex change without interfering with the stability of /trunk . Unlike release branches (which may need to be supported forever), feature branches are born, used for a while, merged back to the trunk, and then ultimately deleted. They have a finite span of usefulness.
Again, project policies vary widely concerning exactly when it's appropriate to create a feature branch. Some projects never use feature branches at all: commits to /trunk are a free-for-all. The advantage to this system is that it's simple—nobody needs to learn about branching or merging. The disadvantage is that the trunk code is often unstable or unusable. Other projects use branches to an extreme: no change is ever committed to the trunk directly. Even the most trivial changes are created on a short-lived branch, carefully reviewed, and merged to the trunk. Then the branch is deleted. This system guarantees an exceptionally stable and usable trunk at all times, but at the cost of tremendous process overhead.
Most projects take a middle-of-the-road approach. They commonly insist that /trunk compile and pass regression tests at all times. A feature branch is required only when a change requires a large number of destabilizing commits. A good rule of thumb is to ask this question: if the developer worked for days in isolation and then committed the large change all at once (so that /trunk were never destabilized), would it be too large a change to review? If the answer to that question is “ yes, ” the change should be developed on a feature branch. As the developer commits incremental changes to the branch, they can be easily reviewed by peers.
Finally, there's the issue of how to best keep a feature branch in “ sync ” with the trunk as work progresses. As we mentioned earlier, there's a great risk to working on a branch for weeks or months; trunk changes may continue to pour in, to the point where the two lines of development differ so greatly that it may become a nightmare trying to merge the branch back to the trunk.
This situation is best avoided by regularly merging trunk changes to the branch. Make up a policy: once a week, merge the last week's worth of trunk changes to the branch.
When you are eventually ready to merge the “ synchronized ” feature branch back to the trunk, begin by doing a final merge of the latest trunk changes to the branch. When that's done, the latest versions of branch and trunk are absolutely identical except for your branch changes. You then merge back with the --reintegrate option:
Another way of thinking about this pattern is that your weekly sync of trunk to branch is analogous to running svn update in a working copy, while the final merge step is analogous to running svn commit from a working copy. After all, what else is a working copy but a very shallow private branch? It's a branch that's capable of storing only one change at a time.
You are reading Version Control with Subversion (for Subversion 1.7), by Ben Collins-Sussman, Brian W. Fitzpatrick, and C. Michael Pilato.

Feature branching your way to greatness.
Or task branching your way there. Or release branching. You choose.
Almost all version control systems today support branches–independent lines of work that stem from one central code base. Depending on your version control system, the main branch may be called master, mainline, default, or trunk. Developers can create their own branches from the main code line and work independently alongside it.
Why bother with branching?
Branching allows teams of developers to easily collaborate inside of one central code base. When a developer creates a branch, the version control system creates a copy of the code base at that point in time. Changes to the branch don't affect other developers on the team. This is a good thing, obviously, because features under development can create instability, which would be highly disruptive if all work was happening on the main code line. But branches need not live in solitary confinement. Developers can easily pull down changes from other developers to collaborate on features and ensure their private branch doesn’t diverge too far from the master.
Branches aren't just good for feature work. Branches can insulate the team from important architectural changes like updating frameworks, common libraries, etc.
Three branching strategies for agile teams.
Branching models often differ between teams, and are the subject of much debate in the software community. One big theme is how much work should remain in a branch before getting merged back into master.
Release branching.
Release branching refers to the idea that a release is contained entirely within a branch. This means that late in the development cycle, the release manager will create a branch from the master (e. g., “1.1 development branch”). All changes for the 1.1 release need to be applied twice: once to the 1.1 branch and then to the master code line. Working with two branches is extra work for the team and it's easy to forget to merge to both branches. Release branches can be unwieldy and hard to manage as many people are working on the same branch. We’ve all felt the pain of having to merge many different changes on one single branch. If you must do a release branch, create the branch as close to the actual release as possible.
Release branching is an important part of supporting versioned software out in the market. A single product may have several release branches (e. g., 1.1, 1.2, 2.0) to support sustaining development. Keep in mind that changes in earlier versions (i. e., 1.1) may need to be merged to later release branches (i. e., 1.2, 2.0). Check out our webinar below to learn more about managing release branches with Git.
Feature branching.
Feature branches are often coupled with feature flags–"toggles" that enable or disable a feature within the product. That makes it easy to deploy code into master and control when the feature is activated, making it easy to initially deploy the code well before the feature is exposed to end-users.
Another benefit of feature flags is that the code can remain within the build but inactive while it's in development. If something goes awry when the feature is enabled, a system admin can revert the feature flag and get back to a known good state rather than have to deploy a new build.
Task Branching.
At Atlassian, we focus on a branch-per-task workflow. Every organization has a natural way to break down work in individual tasks inside of an issue tracker, like Jira Software. Issues then becomes the team's central point of contact for that piece of work. Task branching, also known as issue branching, directly connects those issues with the source code. Each issue is implemented on its own branch with the issue key included in the branch name. It’s easy to see which code implements which issue: just look for the issue key in the branch name. With that level of transparency, it's easier to apply specific changes to master or any longer running legacy release branch.
Since agile centers around user stories, task branches pair well with agile development. Each user story (or bug fix) lives within its own branch, making it easy to see which issues are in progress and which are ready for release. For a deep-deep dive into task branching (sometimes called issue branching or branch-per-issue), grab some popcorn and check out the webinar recording below–one of our most popular ever.
Now meet branching's evil twin: the merge.
We’ve all endured the pain of trying to integrate multiple branches into one sensible solution. Traditionally, centralized version control systems like Subversion have made merging a very painful operation. But newer version control systems like Git and Mercurial take a different approach to tracking versions of files that live on different branches.
Branches tend to be short-lived, making them easier to merge and more flexible across the code base. Between the ability to frequently and automatically merge branches as part of continuous integration (CI), and the fact that short-lived branches simply contain fewer changes, "merge hell" becomes is a thing of the past for teams using Git and Mercurial.
That's what makes task branching so awesome!
Validate, validate, validate.
A version control system can only go so far in affecting the outcome of a merge. Automated testing and continuous integration are critical as well. Most CI servers can automatically put new branches under test, drastically reducing the number of "surprises" upon the final merge upstream and helping to keep the main code line stable.
Agile has had a huge impact on me both professionally and personally as I've learned the best experiences are agile, both in code and in life. You'll often find me at the intersection of technology, photography, and motorcycling. Find me on Twitter! danradigan.
Sign up for more articles.
Obrigado por inscrever-se!
How to do scrum with Jira Software.
A step-by-step guide on how to drive a scrum project, prioritize and organize your backlog into sprints, run the Scrum ceremonies and more, all within Jira Software.
Git branching for agile teams.
Moving to Git opens up a whole new level of agility for software teams. Here's how to design branching schemes for shipping both SaaS and installed products.

No comments:

Post a Comment