Quando você deve ramificar?

107

Ao trabalhar com um sistema SCM, quando você deve ramificar?

Ben Aston
fonte

Respostas:

59

Existem vários usos para ramificação. Um dos usos mais comuns é separar projetos que antes tinham uma base de código comum. Isso é muito útil para fazer experiências com seu código, sem afetar o tronco principal.

Em geral, você veria dois tipos de ramificação:

  • Ramificação de recurso: se um recurso específico é perturbador o suficiente para que você não queira que toda a equipe de desenvolvimento seja afetada em seus estágios iniciais, você pode criar uma ramificação para fazer esse trabalho.

  • Ramificação de correções: Enquanto o desenvolvimento continua no tronco principal, uma ramificação de correções pode ser criada para conter as correções da última versão lançada do software.

Você pode estar interessado em verificar o seguinte artigo, que explica os princípios de ramificação e quando usá-los:

Daniel Vassallo
fonte
Nunca ouvi ou pensei sobre o uso comum que você mencionou, mas é uma ideia muito legal. Eu realmente poderia usar isso no próximo projeto. Obrigado por apontar isso.
Nils Riedemann
82

Em termos gerais, o objetivo principal da ramificação (um recurso VCS - Sistema de Controle de Versão) é atingir o isolamento do código .

Você tem pelo menos um branch, que pode ser suficiente para o desenvolvimento sequencial, e é usado para muitas tarefas sendo gravadas (confirmadas) nesse mesmo branch exclusivo.

Mas esse modelo mostra rapidamente seu limite:

Quando você tem um esforço de desenvolvimento (refatoração, evolução, correções de bugs, ...) e você percebe que não pode fazer essas mudanças com segurança no mesmo branch do que o seu branch de desenvolvimento atual (porque você quebraria a API ou introduziria código que quebraria tudo), então você precisa de um outro ramo.
(Para isolar esse novo código para o legado, apesar dos dois conjuntos de códigos será merge mais tarde)

Portanto, esta é sua resposta:
Você deve ramificar sempre que não puder prosseguir e registrar dois esforços de desenvolvimento em um ramo.
(sem ter uma história terrivelmente complicada para manter).


Um branch pode ser útil mesmo se você for o único trabalhando no código-fonte, ou se você for muitos.
Mas você não deve fazer "um branch por desenvolvedor":
o propósito de "isolamento" é feito para isolar um esforço de desenvolvimento (uma tarefa que pode ser tão geral quanto "vamos desenvolver a próxima versão do nosso software" ou tão específica quanto "vamos consertar bug 23 "),
para não isolar um" recurso " .

(um branch chamado "VonC" não significa nada para outro desenvolvedor: E se "VonC" deixar o projeto? O que você deve fazer com ele?
um branch chamado "bugfix_212" pode ser interpretado no contexto de um sistema de rastreamento de bugs, por exemplo , e qualquer desenvolvedor pode usá-lo com pelo menos alguma ideia sobre o que ele deve fazer com ele)

Uma ramificação não é uma tag (SVN é um sistema de revisão que tenta propor recursos de versionamento como ramificação e marcação através de diretórios com cópia de arquivo barata: isso não significa que uma tag é uma ramificação)

Definir um branch significa também definir um fluxo de trabalho de fusão : você precisa saber onde fundir seu branch quando terminar de usá-lo.
Para isso, o capítulo 7 da Practical Perforce (Laura WINGERD - O'Reilly) é uma boa introdução (agnóstica VCS) para mesclar workflows entre diferentes tipos de branches: "" How Software Evolves "(pdf)

Ele define o termo codeline (ramificação que registra etapas de evolução significativas do código, seja por meio de tags em determinados pontos, ou por meio de fusão importante de volta para a ramificação)

Ele apresenta o modelo de linha principal (uma linha de código central para registrar lançamentos) e descreve vários propósitos para ramificação:

  • Fluxos de desenvolvimento ativos : uma linha de código persistente quando vários desenvolvimentos sequenciais ocorrem
  • ramos de tarefas : ramos de curta duração para tarefas mais específicas (correção de bug é um clássico, mas você também pode definir um ramo para um esforço de mesclagem que você sabe ser complexo de concluir: você pode mesclar, confirmar e testar nesse ramo de tarefa sem introduzir problemas para o principal ramo de desenvolvimento atual)
  • branch de teste : para preparar um lançamento, com alguns dados específicos de pré-produção ou arquivos de configuração.
  • Ramos privados, ramos ad hoc e ramos esparsos : para tarefas muito pequenas, apenas para poder comprometer algum trabalho em andamento sem esperar pela conclusão formal ou revisão de teste.
    Isso permite "cometer cedo, cometer com frequência".

Outros conceitos interessantes em torno do VCS: conceitos básicos
(sobre o ClearCase originalmente, mas também válido para qualquer VCS)

VonC
fonte
19

Todos os SCMs do século 21 estão dizendo a você:

Ramifique para cada tarefa em que você trabalhar , não importa se é um novo recurso, uma correção de bug, um teste, o que for. Isso é chamado de ramo de tópico e muda a maneira como você trabalha com seu SCM.

Você obtém:

  • Melhor isolamento
  • Melhor rastreabilidade -> você associa tarefas com branches, não conjuntos de alterações individuais, o que o torna livre para fazer commit quantas vezes quiser e não impõe um limite como "um check-in por tarefa".
  • As tarefas são independentes (normalmente começando de uma linha de base estável, então você só se concentra em seu código, não em corrigir bugs de seu pessoal), e você pode escolher se deseja integrá-los em algum ponto ou mais tarde, mas eles estão sempre sob controle de versão
  • Você pode revisar o código facilmente (no controle de versão, não em besteiras de pré-commit) antes de chegar à linha principal

Ferramentas que podem fazer isso:

Ferramentas que NÃO PODEM fazer:

  • SVN
  • CVS
  • VSS
  • TFS
  • Perforce
pablo
fonte
1
Por que você não pode fazer isso com o SVN ??
yegor256
4
SVN não é uma boa mesclagem. Devido à falta de rastreamento de mesclagem adequado. Até porque criar um branch não é tão barato quanto nos que apontei, acaba sendo um pesadelo em condições reais.
pablo
Melhor rastreabilidade: Por que você quer se comprometer quantas vezes quiser? Uma vez por tarefa não é suficiente quando a tarefa não é um recurso complicado? Além disso, bugs de pessoas podem facilmente chegar ao branch principal e torná-lo não "estável" e não "seguro", bem no momento em que se fundem.
Paiman Samadian
@PaimanSamadian: "Uma vez por tarefa não é suficiente quando a tarefa não é um recurso complicado?" Certo. Da mesma forma, quando a tarefa é complicada, um commit não é suficiente (eu comprometo a cada poucos minutos se as coisas estiverem indo bem). Por que forçar um commit por tarefa? • "Também bugs de pessoas podem facilmente chegar ao branch principal" Na verdade, não. Parte do fluxo de trabalho de um branch de recurso é que ele torna possível a revisão e o teste do código antes que o código seja mesclado no branch principal.
Marnen Laibow-Koser
1
Os check-ins múltiplos do @PaimanSamadian são ótimos para explicar as mudanças intermediárias e facilitar a revisão. Além disso, se você estiver trabalhando algumas horas em algo, vários check-ins são ótimos.
pablo
8

Também depende da ferramenta SCM que você está usando. SCMs modernos (git, mercurial, etc.) tornam cada vez mais fácil criar e destruir branches sempre que necessário. Isso permite que você, por exemplo, crie um branch por bug no qual está trabalhando. Depois de mesclar seus resultados no tronco, você descarta o galho.

Outros SCMs, por exemplo, subversion e CVS, têm um paradigma de ramificação muito mais "pesado". Isso significa que um branch é considerado apropriado apenas para algo maior do que um patch de linha de vinte e poucos anos. Lá, as ramificações são classicamente usadas para rastrear trilhas inteiras de desenvolvimento, como uma versão anterior ou futura do produto.

Fred
fonte
5

Quando você precisa fazer alterações significativas e / ou experimentais em sua base de código, especialmente se você deseja fazer alterações intermediárias, sem afetar o tronco.

Dominic Rodger
fonte
5

Depende do tipo de SCM que você está usando.

Nas versões distribuídas mais novas (como git e mercurial), você cria branches o tempo todo e reaparece de qualquer maneira. Freqüentemente, trabalho em um branch separado por um tempo só porque alguém quebrou a compilação na linha principal ou porque a rede caiu, e depois mesclo as alterações novamente quando estiver consertado, e é tão fácil de fazer que nem chega a ser chato .

O documento (curto e legível) que mais me ajudou a entender o que acontecia nos sistemas distribuídos é: UnderstandingMercurial .

Nos sistemas mais antigos com um repositório central, (como CVS, SVN e ClearCase), então é uma questão muito mais séria que precisa ser decidida em um nível de equipe, e a resposta deve ser mais como 'manter uma versão antiga enquanto permite desenvolvimento para continuar na linha principal ', ou' como parte de um grande experimento '.

O modelo distribuído é muito melhor, eu acho, e falta apenas boas ferramentas gráficas para se tornar o paradigma dominante. No entanto, não é tão amplamente compreendido e os conceitos são diferentes, por isso pode ser confuso para novos usuários.

John Lawrence Aspden
fonte
3

Acho que o conselho de Laura Wingerd & Christopher Seiwald, da Perforce, é muito conciso e útil:

* Branch only when necessary.
* Don't copy when you mean to branch.
* Branch on incompatible policy.
* Branch late.
* Branch, instead of freeze.

Consulte http://www.perforce.com/sites/default/files/pdf/perforce-best-practices.pdf para obter uma explicação detalhada de cada um deles e outras práticas recomendadas.

Lester Cheung
fonte
3
As pessoas P4 costumavam falar isso, mas hoje em dia o marketing deles fala algo diferente. Eles tentaram evitar ramificações por anos, simplesmente porque não conseguem fazer ramificações de tarefas ou tópicos tão bem quanto outros sistemas como o Git
pablo,
Resposta em 2015! A razão para evitar o branch é evitar a necessidade de mesclar - não porque o Perforce não tinha branch de tarefa / tópico (você pode fazer "branch de tarefa" em streams - no Perforce chamamos de "streams de tarefa". Como outros mencionaram - ramificação está implícita no DVCS e a questão se torna irreverente. Acho que a discussão deve ser limitada a apenas ferramentas que funcionam no modo cliente-servidor. Ou DVCS usado de forma centralizada (desde a versão 2015.1 você pode usar o Perforce em modo DVCS - o melhor dos dois mundos).
Lester Cheung
2

Existem vários propósitos para ramificação:

  1. Ramos de recurso / bug. Ramificações dinâmicas e ativas que são movidas de volta ao tronco quando o recurso / correção de bug é concluído.
  2. Ramificações estáticas (tags no Subversion, embora em essência apenas uma 'ramificação normal'). Eles fornecem um instantâneo estático de, digamos, um lançamento. Mesmo que eles possam ser trabalhados, eles permanecem intocados.
Wim Hollebrandse
fonte
1

A necessidade de ramificação também pode surgir:

  • quando você deseja fornecer um hotfix para um cliente específico (digamos, importante) e não tem certeza se a correção fará parte de versões futuras

  • sateesh
    fonte
    1

    Sempre que você sentir vontade.

    Você provavelmente não o fará com muita frequência se trabalhar com um SCM centralizado, uma vez que os branches fazem parte do repositório oficial, e isso realmente não convida a muita experimentação, sem mencionar que as fusões realmente prejudicam.

    OTOH, não há diferença técnica entre um branch e um checkout em SCMs distribuídos, e as mesclagens são muito mais fáceis. Você terá vontade de ramificar com muito mais frequência.

    apenas alguem
    fonte
    0

    Quando você precisa fazer alterações, com base em seu branch atual, não destinadas para a próxima versão desse branch (e não antes).

    Por exemplo, geralmente trabalhamos no tronco. Na época do lançamento, alguém precisará fazer uma alteração que não queremos no lançamento atual (pode ser antes do lançamento, no momento é geralmente após o lançamento). É quando nós ramificamos, para colocar a versão em sua própria ramificação e continuar o desenvolvimento para a próxima versão no tronco.

    Andrew Aylett
    fonte
    0

    Deixando todos os detalhes técnicos de lado ...

    Ramifique quando você souber que é mais fácil fundir novamente!

    Lembrando que a fusão sempre será efetuada com a forma como o trabalho é realizado em um projeto.

    Uma vez que isso seja alcançado, todas as outras questões terciárias entrarão em jogo.

    Syed M Shaaf
    fonte