Porquê e como usar o GitFlow — Parte 1

Tenho notado por aí que muita gente usa o Git de maneira padrão. Ou seja, coda, add, commita e sobe pro Git.

Apesar de simples, esse é o fluxo (flow) "padrão" da ferramenta. E, por mais simples que seja, já é um flow que pode ser usado naturalmente por que está desenvolvendo um produto ou sistema.

Um dos pontos fracos desse flow é a fragilidade quando se tem mais de uma pessoa trabalhando no mesmo projeto. Explico: imagine 2 devs fazem o clone inicial de um projeto e começam cada um a fazer commits locais na branch master. Tudo vai bem até uma funcionalidade específica que foi solicitada e já commitada precisar sair do próximo deploy. E agora? E se os 2 devs já fizeram o push para a branch remota. Complica mais um pouco?

Apesar de ser possível "desfazer" os commits da funcionalidade em questão, isso vai requerer um trabalho manual de busca, identificação e tratamento do código que vai sair da branch master.

É claro que um cenário simples como esse (2 devs e 1 projeto) pode ser resolvido com o uso de branches. Contudo, projetos com muitos desenvolvedores, com processos de code review e aprovação de features acabam necessitando fluxos mais complexos.

Alguns fluxos são mais conhecidos pois já foram implementados por projetos e empresas e já foram testados e validados. Um desses fluxos é o Gitflow.

Em resumo: o modelo se baseia em 2 branches principais:

  • master
  • develop

A branch master deve der bem familiar para quem já trabalha com o Git. Nesse modelo ela representa (tanto a local quanto a remota `origin`) o código que reflete a versão do produto que está em produção.

A branch `develop` deve refletir as novas features que já estão prontas e que serão disponibilizadas na próxima versão. Ou seja, quando todas as funcionalidades da próxima versão estiverem prontas (leia-se completamente prontas e testadas) e commitadas nessa branch, ela deve ser mergeada (e taggeada) com a branch master de alguma forma (veremos daqui a pouco como). Assim, por definição, todo merge com a master passa a valer como uma versão de produção.

Branches de Suporte

Essas branches possuem esse nome pois vão servir para apoiar os devs em fazer o desenvolvimento em paralelo sem afetar o trabalho uns dos outros e planejar melhor as funcionalidades e releases da aplicação. São elas:

  • Branches de features
  • Branches de releases
  • Branches de hotfix

Cada branch dessa possui uma utilidade específica e algumas regras que devem ser seguidas quanto a partir de que outra branch elas precisam se originar e para qual(ais) outras branches elas deve ser mergeadas.

Feature Branches

São nelas que todo o desenvolvimento de uma nova funcionalidade deve feito. É sempre bom definir uma convenção para o nome dessas branches. Alguns lugares usam `feature-<nome da feature>`. Em outros se usa o modelo de `feature/<nome da feature>`. Em alguns o nome da branch é o ID da ferramenta de controle de projeto (Jira, Trello, etc.). O importante é definir um padrão.

Essa branch só deve existir enquanto a funcionalidade estiver em desenvolvimento. Quando a funcionalidade está pronta, ela deve ser mergeada com a `develop` (lembre-se, a master é somente código de produção). Branches de funcionalidade tipicamente não existem no `origin` (se faz o merge com a `develop` localmente e se apaga a feature branch antes do push).

Para criar uma feature branch (que na verdade é só uma branch), usa-se o seguinte comando:

$ git checkout -b feature-myfeature develop

Ou seja, estamos criando uma nova branch chamada `feature-myfeature` a partir da branch `develop`.

Quando se termina a funcionalidade precisamos fazer o merge com a branch `develop` (lembre-se de sempre rodar todos os testes antes):

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff feature-myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d feature-myfeature
Deleted branch feature-myfeature (was 05e9557).
$ git push origin develop

A opção `no-ff`garante que seja gerado um objeto de commit e assim não fazendo que não percamos o histórico das mudanças.

No próximo post, falaremos das release branches. Até lá.