Ramificação do Lean: simplificação de mesclagem e ramificação

Nicola Paolucci
Nicola Paolucci
Voltar para a lista

Os fluxos de trabalho de branch vão de simples a complexos, robustos e defensivos. Qual é o nível de complexidade e proteção necessário para sua empresa? Esta publicação aborda o ajuste entre agilidade e robustez, com algumas diretrizes para escolher sua própria aventura git e lições aprendidas dentro da Atlassian.

O objetivo deste artigo é apresentar os insights e as ferramentas que você pode usar para decidir como escolher o modelo branches mais eficaz para sua equipe.

Pensamentos orientadores

  • Confie no merge
  • Fique longe de modelos extremos de branches
  • Simplifique e nivele hierarquias de branches sempre que possível
  • Considere como seu processo de desenvolvimento e suas ferramentas impactam as decisões do modelo de branches

Confie no merge

O primeiro passo para escolher o modelo de branches ideal é confiar no merge. Esta orientação serve mais para equipes que adotaram recentemente o git. Se você passou desta etapa e adotou o merge, pule este parágrafo.

Enquanto em sistemas mais antigos você pode ser levado a medidas extremas (como evitar merges a todo custo ou contratar uma equipe especial para cuidar do inferno do merge) acontece que os merges não são um evento no Git. Essa situação ocorre por vários fatores importantes:

  • Como os branches são muito baratos e rápidos, o git incentiva branches de curta duração e uma integração rápida.
  • Os merges são locais no git, portanto, o resultado de um merge quase sempre é imediato.
  • O git conhece a ancestralidade dos branches e só faz o merge dos commits que são relevantes em vez de toda a árvore de trabalho plana. Esse comportamento quase sempre resulta em menos conflitos.
  • Você tem uma infinidade de estratégias de merge à sua disposição. Por causa disso, você vai amar o merge e, por consequência, também vai amar usar branches. Usar branches e merges fica tão fácil que algumas equipes acabam com o problema oposto, elas acabam exagerando. Então, como acontece com tudo na vida, mantenha o equilíbrio e não exagere.

Fique longe de extremos de branches

Se você olhar para modelos de branches em geral — antes e depois do advento do git — você vai ver que eles se situam em um espectro que vai do simples ao em camadas. Os extremos podem ser problemáticos. Vou mostrar algumas paradas na continuidade de branches e por que você pode querê-las ou não.

Extremo do branch único

Memória do passado de subversão: um branch para a todos governar. Durante anos, as equipes de software (inclusive eu) trabalharam com apenas um branch, o tronco, com sol ou chuva, com recursos completos ou incompletos, com builds funcionando ou quebrados. Esse processo costumava funcionar e ainda funciona hoje. Mas ele deixou de ser o mais eficiente.

O mundo de um único branch que amávamos odiar e com o qual crescemos e que alguns de nós ainda usamos era mais ou menos assim:

Tronco

Equipes que recém adotaram o git ou equipes que querem manter seu fluxo de trabalho podem tentar reproduzir a mesma sensação. Mesmo que o trunk no git -speak agora seja chamado de main, você pode trabalhar com um único branch no git, o que é mais ou menos assim:

Rebase no recurso

Todo mundo trabalha no main, ninguém trabalha nos branches e cada desenvolvedor usa o rebase para se manter atualizado com as últimas alterações. Este formato é muito próximo de um modelo de branches de subversão somente tronco de estilo antigo.

Não é incomum para mim ouvir equipes modernas que — sim — adotaram algum nível de branches, mas são nostálgicas e impõem uma regra de squash on commit que nivela o histórico e faz com que o main fique exatamente igual à imagem acima.

O que falta nelas? Contexto e rastreabilidade. Para mais informações, leia meu artigo sobre o debate merge vs. rebase.

Qual é a principal desvantagem de um único branch? Quando o main está quebrado, o trabalho de todos é interrompido. É verdade que, com o git, os desenvolvedores têm todo o histórico do projeto à sua disposição. É fácil voltar no tempo antes da ruptura e continuar trabalhando até que o problema seja resolvido. Mas é verdade também que, se um desenvolvedor sabe como fazer essa viagem no tempo sem problemas, ele também está usando seus próprios branches locais para estacionar seu trabalho.

Muitas camadas de branches de integração

No outro extremo do espectro está uma empresa que gosta demais de formalizar processos e adota o uso branches de uma forma que complica em vez de simplificar vidas.

Por exemplo, dê uma olhada no seguinte modelo de branch:

Branches demais

Neste exemplo, a equipe cria um branch para cada história de usuário; a partir de cada história de usuário, por sua vez, um branch é criado para cada item; e, a partir de cada branch de item, um branch é criado para cada subtarefa. Em seguida, tudo vai para o branch next, do qual eles lançam para o main.

Uma coisa que já foi dita e é verdade: usar branches e merges é tranquilo no git, mas complicar seu processo vai afetar a velocidade de equipe de qualquer maneira.

Simplifique e nivele hierarquias de branches sempre que possível

Pelo menos agora sabemos que devemos evitar os extremos. O que é, então, um bom compromisso entre estrutura e flexibilidade? É fácil identificar o ponto ideal da sua equipe respondendo a algumas perguntas críticas:

  • Qual é o número mínimo de branches de longa duração que eu preciso para dar suporte ao meu projeto?
  • Preciso manter versões mais antigas do meu software ou não? Em geral, você deve tentar nivelar as hierarquias de branches o máximo possível, compatível com a força do seu conjunto de testes, a confiança e o nível de responsabilidade que você coloca em sua equipe, sua tolerância a problemas de produção.

Na Atlassian, usamos um modelo de branches relativamente plano em várias de nossas equipes, tanto para nossos produtos BTF (atrás do firewall) quanto para nossa oferta sob demanda (Cloud).

Um branch por história de usuário ou um branch por item (item do Jira)?

A granularidade dos branches importa. Se eles são muito grosseiros e forçam muitas pessoas a trabalhar juntas, você se depara com os problemas de branch único que destaquei antes, se você criar (e publicar) muitos branches, seu processo de revisão e o quadro geral podem ficar confusos e inchados.

Descobrimos que uma boa granularidade na escolha do escopo dos branches é "um branch por item".

Fluxo de trabalho saudável #1: branch principal único estável, aproveitar os branches, mas manter a simplicidade

Meu artigo recente sobre fluxos de trabalho git simples mostrou um modelo de branches simples para entrega contínua. Que está centrado na noção de que o main é o branch de produção. Qualquer commit para o main é uma versão de produção marcada. É um ótimo fluxo de trabalho, por exemplo, para aplicativos da web, frentes de lojas, SaaS e, em geral, para situações em que você não precisa manter versões históricas mais antigas.

Fluxo de trabalho saudável #2: faça o simples, mas mantenha versões mais antigas

Quando você precisa manter e oferecer suporte a versões mais antigas de seus produtos, um único main estável não é suficiente. A solução é ter branches de lançamento de longa duração para cada versão a que sua equipe precisa oferecer suporte. As mudanças fluem sempre dos branches mais antigos para os mais recentes, nunca na direção oposta. Para entender o motivo, consulte o texto sobre a essência dos fluxos de trabalho baseados em branches.

Branches de versão de longa duração

Branches extras de integração quando necessário

Desde que você saiba o motivo exato de não poder ficar sem ela, pode ser útil isolar o trabalho de uma pequena equipe de desenvolvedores por mais tempo do que uma única iteração. Para conseguir esse resultado, você pode configurar um branch de integração. O branch deve ser atualizado com o que for mais recente do main sempre que possível, para simplificar o merge final.

Por exemplo, dentro da equipe do Bitbucket Server, branches de integração adicionais acontecem 1-2 vezes por ciclo de lançamento — o que, no caso deles, é de cerca de seis semanas. É um comportamento necessário quando a equipe tem vários fluxos de trabalho que eles precisam manter isolados por um tempo.

O processo e as ferramentas de desenvolvimento têm impacto no modelo de branches

O processo de desenvolvimento e as ferramentas da sua equipe têm um impacto poderoso nas decisões do modelo de branches e na agilidade e eficácia da equipe.

Se você usar os recursos de pull request do Bitbucket Server ou do Bitbucket Cloud, vai poder revisar o trabalho de seus colegas direto, sem esmagar os branches em um único commit.

E, por fim, quanto mais informações você tiver sobre o status e os resultados de suas equipes, vai poder permitir que todos trabalhem em paralelo com mais liberdade.

Imagine se você pudesse — só de olhar — ter uma noção do status de todos os builds, pull requests, branches e commits de um determinado recurso. A boa notícia é que essa utopia é real hoje. Fique maravilhado com esta beleza:

Painel de desenvolvimento do JIRA

*Este painel de desenvolvimento está disponível com o Jira 6.2, o Bitbucket Server 2.10+ e o Bamboo 5.4.

O que você vê acima é o painel "Desenvolvimento" no Jira. Quando ele é combinado com o Bitbucket e o Bamboo, você tem um único lugar onde pode consultar todas as suas atualizações de desenvolvimento. Esse painel, disponível em todos os seus itens e quadros rápidos do Jira, permite que todos no ciclo de desenvolvimento estejam sincronizados. Fique por dentro do status dos seus branches, identifique aquelas com builds quebrados e monitore suas implementações sem precisar procurar informações de novo. Gaste tempo criando e lançando um ótimo código, em vez de rastreando.

Conclusões

Este artigo foi mais longo do que eu esperava, mas espero que lhe dê um bom conjunto de diretrizes sobre como escolher um modelo de branch eficaz e enxuto para suas equipes. Siga as minhas publicações em @durdn e a incrível equipe do @Bitbucket para arrasar no DVCS.

Pronto(a) para aprender Git?

Tente este tutorial interativo.

Comece agora mesmo