Branching
|
Branch e head |
- Branching é a duplicação de um branch
- Depois do branching, cada branch pode ser modificado separadamente em paralelo
- O branching implica na capacidade de posteriormente mergear ou integrar as mudanças
- Poderá haver algum esforço para resolver conflitos de merge:
- Conflito textual × conflito semântico
- Principais fatores que influenciam o esforço na resolução de conflitos:
- Complexidade das linhas de código em conflito
- Modularidade: acoplamento × coesão
- Tamanho dos branches: número de linhas de código modificadas ou adicionadas depois do branching
- Via de regra, quando dobramos o tamanho dos branches:
- O valor esperado e a incerteza do esforço na resolução de conflitos quadruplica
|
Branching e merge |
Vantagens e Desvantagens de Branching
Vantagens
- Permite que partes do software sejam desenvolvidas em paralelo
- Permite que os desenvolvedores isolem as mudanças numa base de código estável
- Facilita a manter várias versões em produção
Desvantagens
- Menor interação entre os membros do time
- Branchear é fácil, mergear é difícil
- Não há como criar um algoritmo para resolver conflitos automaticamente
- Muitos times gastam uma quantidade excessiva de tempo lidando com seu emaranhado de branches
Git-flow
Criado por Vincent Driessen em 2010.
|
Modelo de Git-flow |
Branch Principal ou Tronco
- No Git-flow, o branch principal é chamado
develop
Feature Branching
- Um branch separado para cada feature
- Tem origem no
develop
- Pode ter qualquer nome que não comece com
release
ou hotfix
- O escopo do branch deve ser definido precisamente na sua criação
- Nunca realizar tarefas fora do escopo pré-definido na branch
- Quando houver novos commits no
develop
:
- Mergeie o
develop
para o branch do feature
- Quando terminar o feature:
|
Branch de feature |
Branches de Release
- Branches de release são cortados de um commit específico no
develop
- Convenção de nomenclatura
release-v<n>.<m>
- Não permite que novos features sejam adicionados ao release
- Os desenvolvedores que trabalham no release se concentram exclusivamente em remover quaisquer defeitos que impeçam o release de estar pronto para produção
- Se não há mais falhas para lidar:
- O branch está pronto para release em produção
- Essas correções devem ser mergeadas ao
develop
- Conforme mais commits modificam o branch principal:
- Fica cada vez mais difícil mergear o branch de release no branch principal
- É muito comum negligenciar a integração das correções
|
Branch de release |
- Algumas pessoas preferem a criação dessas correções no
develop
, (como Google)
- Quando estiverem funcionando:
- Cherry-pická-los no branch de release
- Desvantagens:
- Muitos times acham difícil fazer isso
- Pode ser necessário retrabalhar as correções no branch de release
|
Aplicar correções no branch principal |
- Os branches de release são necessários para projetos em que existem várias versões em produção
|
Branches de release com múltiplas versões em produção |
Branches de Hotfix
- Branch para capturar trabalho para corrigir um defeito de produção urgente
- Abrir o branch na última versão de release
- Quando o hotfix for concluído:
- O hotfix deve ser mergeado ao
develop
- Se houver um branch de release aberto para a próxima versão:
- O hotfix precisará ir para lá também
|
Branch de hotfix |
- O trabalho de hotfix pode ser feito no branch de release
- É possível fazer os hotfixes no branch principal, cherry-pická-los para o branch de release
|
Hotfix em um branch de release |
Branch de Produção
- Branch que rastreia as versões entregues para produção
- Para preparar um release para produção:
- Abrir um branch de release para estabilizar o produto
- Quando estiver pronta: copiá-lo para um branch de produção de longa duração
- No Git-flow, o branch de produção é chamado de
master
- Uma alternativa ao uso de branch de produção é aplicar um esquema de tagueamento
|
Branch de produção |
Vantagens e Desvantagens de Git-flow
Vantagens
- O histórico de commits do repositório mostra um registro detalhado do que realmente aconteceu
- É adequado para projetos em que existem várias versões em produção
Desvantagens
- O histórico de Git se torna ilegível, cheia de uma série confusa de commits de merge
- O branch de produção é desnecessário
- Com 5 tipos de branches, o Git-flow é desnecessariamente complicado
- Não adequado para Delivery Contínuo
- Permite branches de feature de longa duração
- Branch principal não pronto para o realease
OneFlow
Proposta no artigo Git-flow considered harmful por Adam Ruka em 2015.
|
Modelo de OneFlow |
- OneFlow chama seu branch principal de
master
- O branch de produção é substituído por um esquema de tagueamento
- Todos os outros branches (feature, release, hotfix) são temporários, usados apenas como uma conveniência para compartilhar código com outros desenvolvedores e como uma medida de backup
- Os features são integrados diretamente (rebase) no
master
, de forma a manter um histórico linear
- Os releases e hotfixes são feitos de forma semelhante ao Git-flow
Vantagens e Desvantagens de Oneflow
Vantagens
- O histórico do Git será mais limpo, menos confuso, mais legível
- O histórico de commits mostra a história de como o projeto foi feito
- O histórico do Git é passado a limpo
- É adequado para projetos em que existem várias versões em produção
Desvantagens
- Alguns times têm dificuldade de usar comandos para rescrita do histórico
- Não adequado para o Delivery Contínuo
- Permite branches de feature de longa duração
- Branch principal não pronto para o release
GitHub Flow
Criado por Scott Chacon em 2011.
- GitHub flow chama o branch principal de
master
- Única versão em produção
- Branch principal pronto para release
- Branches de releases não são necessários
- Problemas de produção são corrigidos da mesma maneira que features regulares, assim não há necessidade de branches de hotfix
- Feature branching de duração limitada
- Revisão pré-integração usando Pull-Request
Branch Principal Pronto para Release
- Manter o branch
master
suficientemente saudável para que o head do master
possa sempre ser colocado diretamente em produção
- Para manter o branch saldável é essencial escrever código de autoteste:
- Conjunto abrangente de testes automatizados, para que possamos ter confiança de que, se esses testes passarem, o código de produção não conterá bugs
- Executados rapidamente, geralmente não mais do que dez minutos
- Toma mais tempo do que o desenvolvimento do código de produção
- Precisamos manter qualidade interna do código alta usando práticas como:
- Análise de programa estática
- Revisão pré-integração
- Se o time usa feature branching de longa duração (> 2 semanas):
- O branch principal pronto para o release pode ser uma barreira para sua melhoria
- Vantagens:
|
Branch principal pronto para release |
Feature Branching de Duração Limitada
- No GitHub flow, os branches de feature são pushados regularmente para o repositório
origin
- Não há integração com o
master
até o feature seja concluído
- O GitHub flow recomenda branches de feature de duração limitada entre dez minutos a duas semanas incluindo a revisão pré-integração
- O estudo do Relatório State Of DevOps indicou que as equipes de desenvolvimento de elite integram com mais frequência do que as de baixo desempenho
- Aumenta a frequência de merges, mas reduz sua complexidade e risco
- Alerta as equipes sobre conflitos com muito mais rapidez
- Aumenta a interação entre os membros do time
Revisão Pré-integração no Modo de Pull Request
- O modelo Pull Request (PR) foi introduzido pelo GitHub, em 2008
- Google pratica modelo semelhante desde 2005
- Todo o código é revisado antes de ser integrado
- O tempo da revisão deve ser aproximadamente metade do tempo de desenvolvimento do código sendo integrado
- Alguns desenvolvedores squasham (rebase) as mudanças em um único commit antes de iniciar um pull request
|
Josh pede ajuda para Brian Brian responde com alguns conselhos |
|
Josh reconhece os comentários de Brian Pusha mais códigos para os atender |
Desenvolvimento Baseado no Tronco
Paul Hammand escreveu um site detalhado para explicar essa abordagem.
- O Desenvolvimento Baseado no Tronco se concentra em fazer todo trabalho no branch principal (chamado de “tronco”), evitando assim qualquer tipo de branch de longa duração
- Integração contínua
- Times podem usar:
- Branch de release (“branch para release”)
- Branch principal pronto para release (“release a partir do tronco”)
- Google pratica Desenvolvimento Baseado no Tronco:
- 2+ bilhões de linhas de código
- Tronco monorepo único
- Checkout esparso
|
Desenvolvimento baseado no Tronco para times menores |
|
Desenvolvimento Baseado no Tronco para times maiores |
Integração Contínua
- Integração contínua:
- Nunca deve ter mais de um dia de trabalho não integrado no repositório local de ninguém
- Toda integração é buildada e testada com código de autoteste
- Não é necessário de que o feature esteja completo
- O time deve conhecer técnicas para ocultar features parciais como:
- Branch por abstração para mudanças mais longas
- Feature flags no desenvolvimento do dia a dia
- Pode integrar diretamente no
master
ou usar branches de feature de curta duração
- Uma ferramenta de CI é um serviço que builda automaticamente o produto de software antes de cada delivery (como Jenkins, Team City, Travis CI, Circle CI, Bamboo)
- As organizações que usam essas ferramentas as usa para buildar automaticamente branches de feature de duração maior que um dia não estão praticando integração contínua
- Um melhor nome para essas ferramentas seria ferramentas de Build Contínuo
Feature Branching × Integração Contínua
Conforme Martin Fowler:
Feature Branching |
Integração Contínua |
❌ Merges menos frequentes ✔ Todo o código em um feature pode ser avaliado quanto à qualidade como uma unidade ✔ O código do feature só é adicionado ao produto quando o feature estiver completo
|
✔ Merges menores ✔ Tempo reduzido para encontrar conflitos ✔ Encoraja a refatoração ✔ Apoia integração em período menor do que o tamanho do feature ❌ Requer compromisso com branches saudáveis (e, portanto, código de autoteste) ✔ Evidência científica de que contribui para um maior desempenho de entrega de software |
Recomendações
- Sempre que estiver pensando em usar um branch, procure entender as consequências no merge
- Certifique-se de entender as alternativas ao Git-flow, como o GitHub flow e o Desenvolvimento Baseado no Tronco, que são geralmente superiores
- Pratique revisão pré-integração com duração de aproximadamente metade do tempo de desenvolvimento do código
- Tente duplicar sua frequência de integração
- Quando a duração dos branches de feature não for maior do que 1 semana:
- Pratique o branch principal pronto para o release