Gitflow: entenda quando e como você deve utilizar
Tags: gitflow, versioncontrol, programming, git
Published: 2022-02-05 04:48:02

Ao utilizar o Git para gerenciar versões de um projeto é preciso decidir o fluxo de trabalho (_workflow_), que irá estabelecer funções bem específicas para diferentes _branches_ e definir quando e como elas devem interagir. Existem diversos fluxos de trabalho consolidados e que podem ser utilizados nos projetos. Neste artigo será abordado sobre o Gitflow, criado por Vincent Driessen.

É comum as pessoas acharem que o Gitflow é um padrão que deve ser estabelecido em qualquer projeto que utilize Git, o que não é uma verdade. Não existe um fluxo de trabalho perfeito onde todos devam seguir, você deve decidir o modelo com base principalmente nas características de implantação do seu projeto.

## Como utilizar?
### _Branches_ básicas e de longa duração

O Gitflow inicia com as seguintes _branches_ básicas

- **Main** (antiga master): contém o código-fonte de produção
- **Develop**: contém o código-fonte que irá integrar todas as alterações desenvolvidas para o ciclo do próximo lançamento

### _Branches_ de suporte

A partir das _branches_ básicas são criadas as _branches_ de suporte. Tais _branches_ podem ser do tipo _feature_, _hotfix_ ou _release_. A imagem abaixo, ilustra a origem para cada tipo de _branch_ e o destino. 


![Gitflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ix9yx6y5jpcbq4lgnrdn.png)

- **Feature**: são ramos para desenvolvimento de **novos recursos do sistema** ou **correções de bugs não emergenciais**, criados a partir da _branch_ **develop**. Após o desenvolvimento, as alterações são mescladas em direção a _branch_ **develop** (origem).
- **Hotfix**: são ramos para desenvolvimento de **correções emergenciais**, criados a partir da *branch* **master**. Após o desenvolvimento, as alterações são mescladas em direção as _branches_ **master** (origem) e **develop**, para que a correção esteja disponível para as novas _features_.
- **Release**: são ramos utilizados para preparação do lançamento da próxima versão de produção. Nelas são permitidas alterações pontuais. Fazendo tais alterações na _release branch_, a *branch* develop fica livre para receber novos recursos da próxima versão. São criadas a partir da **develop** e, após a validação da release, devem ser mescladas em direção a **develop** (origem) e a **master**. O "*merge back*" na develop é importante, pois atualizações críticas podem ter sido adicionadas a _release branch_ e precisam estar acessíveis a novos recursos.

### Pontos importantes
- As _branches_ master e develop são linhas contínuas, ou seja, se mantém durante todo o tempo de projeto.
- As _branches_ de suporte são temporárias, após concluir o propósito e as alterações retornarem para a origem, tais ramos devem ser descartados.
- Não há _merge_ da develop em direção a master diretamente, sempre utiliza-se as _release branches_.
- As _branches_ que realizam **_merge_ em direção a master devem gerar tags**, como será visto na parte prática desse artigo.

## Praticando
Existem ferramentas para auxiliar no dia a dia quanto a este modelo, você não precisará se preocupar com a origem a qual a nova *branch* será criada, para onde deve ocorrer a mesclagem quando o trabalho for concluído e se é necessário criar uma *tag*. A ferramenta irá gerenciar isso para você. Neste artigo será apresentado uma extensão para linha de comando, como é uma extensão, tal recurso não é instalado nativamente com a instalação do Git. 

Considere o link abaixo e as orientações para realizar a instalação:

https://github.com/nvie/gitflow/wiki/Installation

Após a instalação:

- Crie um diretório em seu computador com o nome "gitflow"
- Acesse tal pasta utilizando o git bash
- Execute: `git flow init`
- Altere os prefixos se preferir ou pressione *enter* para cada interação para manter o padrão.

### Criando uma feature *branch*

Para iniciar o desenvolvimento de uma nova *feature* basta executar o comando abaixo: 

    git flow feature start <NOME_FEATURE>

Para esta prática, considere NOME_FEATURE igual a "cache-provider". Após executar, veja que o prefixo configurado no git flow init foi concatenado com "cache-provider". As ações internas envolveram criar uma nova *branch* baseada na develop e um checkout em tal branch.


![Criando uma feature - Gitflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dr2brodkdaxs5xx90ip0.png)

Para demonstração do desenvolvimento da feature "cache-provider" execute os seguintes passos:

- `touch cache-provider.js` (cria um arquivo em branco chamado cache-provider.js no diretório)
- `git add cache-provider.js` (adiciona o arquivo na área de preparo/*staging* para o próximo *commit*)
- `git commit -m "adding a cache provider"` (realiza um *commit* que inclui o arquivo recém criado)
- `git flow feature finish cache-provider` (indica que a *feature* foi concluída e pode ser mesclada para develop)


![Concluindo uma feature - Gitflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uypcnp6re1v8cnlg0g67.png)

Como visto na imagem acima, também não é necessário informar o prefixo na hora de encerrar uma *feature*. Ao concluir uma feature as ações internas que ocorrem são: 
- Mesclagem da *feature* em direção a develop
- Remoção da *branch* criada feature/cache-provider
- *Checkout* na branch develop 

Se você estiver desenvolvendo um novo recurso de forma colaborativa, seria interessante publicar a *feature* após cada *commit* da seguinte forma: 

    git flow feature publish <NOME_FEATURE>

### Criando uma hotfix *branch*

Quando um problema emergencial surge e não há a possibilidade de aguardar a próxima release pode-se utilizar hotfix. Para isso, basta executar o seguinte comando:

    git flow hotfix start <NOME_HOTFIX>

Para esta prática, considere NOME_HOTFIX igual a "template-fix". É importante observar que este tipo de *branch* foi criado baseado na master. Logo após a criação da *branch* é feito um *checkout* no ramo recém criado.

![Criando uma hotfix - Gitflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5j31c5vv1o6fmpnfk7ie.png)

Para demonstração do desenvolvimento da hotfix execute os seguintes passos:  

- `touch template-fix.js`
- `git add template-fix.js`
- `git commit -m "template bug fix"`
- `git flow hotfix finish template-fix` 

Será aberto o editor padrão para solicitar uma **definição da tag e dos commits de merge** (para develop e para a master). **Você deve informar, obrigatoriamente, ambas as descrições** (os merges já possuem uma descrição padrão que você pode manter, mas a tag precisa ser informada).

![Concluindo uma hotfix - Gitflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ninc895n4xnu39bcvnp0.png)

Observe que várias ações foram promovidas: 
- Houve um *merge* da *branch* hotfix em direção a master e develop
- Uma tag foi criada
- A *branch* de hotfix foi deletada 
- Houve um *checkout* novamente para a *branch* develop.

### Criando uma release branch

A correção emergencial já consta nas duas *branches* básicas master e develop, contudo a feature "cache-provider" ainda não está na master. **Qualquer novo recurso ou correção não emergencial é promovido em produção através de _release branches_**. Para isso execute o comando abaixo:

    git flow release start <NOME_RELEASE>

![Criando uma release - Gitflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/26lsyrqc9ukrwoaeyxse.png)

Neste momento, foi realizado *checkout* na *branch* do tipo release que foi criada a partir da *branch* develop. **Este ramo permite correções antes de ser mesclado na branch master, o que justifica um merge de volta para develop**. Nessa prática, não será realizado nenhum tipo de correção, por isso basta executar:

    git flow release finish <NOME_RELEASE>  

![Concluindo uma release - Gitflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cq8wjw1p5hmsomy4ilk2.png)

Observe que várias ações foram promovidas: 
- Houve um *merge* da *branch* release em direção a master e develop
- Uma tag foi criada
- A *branch* de release foi deletada 
- Houve um *checkout* novamente para a *branch* develop.

Guia

A imagem abaixo ilustra bem como você pode utilizar esta extensão para Gitflow por linha de comando.

![Guia Gitflow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ycbcnkfdd204fkjmtqri.png)
Fonte: https://danielkummer.github.io/git-flow-cheatsheet/index.pt_BR.html

## Pontos de atenção 
 - Qualquer novo **recurso ou bug não emergencial deve ser mesclado com a *branch* develop somente quando este estiver confirmado na próxima release**. Isso porque a próxima versão que será promovida em produção é criada a partir da *branch* develop. **Se a cada release** há a necessidade de remover *commits* pois esses foram bloqueados por algum motivo, isso certamente irá gerar um overhead muito grande para a equipe de desenvolvimento
    - Uma alternativa que pode minimizar esse problema é a utilização de [feature toogles](https://martinfowler.com/articles/feature-toggles.html), quando possível
 - É interessante possibilitar testes na própria ramificação de recurso ou bug não emergencial, para que qualquer erro ou um entendimento equivocado seja resolvido antes da integração com a *branch* develop
 - Se não há ferramentas e processos, que possibilitem os testes acima, então os testes serão realizados diretamente na branch develop. Neste caso, é muito importante que todo o time esteja comprometido em agir prontamente para qualquer erro reportado. **Lembre, essa versão é a que será implantada em produção na próxima release**
 - Mudanças de prioridades podem ocorrer, porém se constantemente é necessário remover *commits* da develop, talvez o Gitflow não seja o melhor fluxo de trabalho para este projeto
 - Antes de definir o Gitflow como o modelo que será implantado, estude outros fluxos de trabalho disponíveis. **Dependendo das necessidades você pode considerar outros mais simples** e que envolvam menos passos e preocupações

## Considerações finais
Após a leitura sobre diversos artigos sobre Gitflow, um assunto que considero bastante polêmico no que tange sua utilização, o Gitflow parece funcionar bem para produtos com lançamentos feitos uma vez a cada poucas semanas, porém quando a necessidade é implantar em produção constantemente, talvez seja interessante avaliar outros fluxos de trabalho

Vale destacar a própria [nota de reflexão](https://nvie.com/posts/a-successful-git-branching-model/) do Vincent Driessen, criador do Gitflow:

> This is not the class of software that I had in mind when I wrote the blog post 10 years ago. If your team is doing continuous delivery of software, I would suggest to adopt a much simpler workflow (like GitHub flow) instead of trying to shoehorn git-flow into your team.

Quer aprender mais sobre Git? Aprenda no mais novo curso de [Git - Básico ao avançado](https://www.udemy.com/course/git-basico-ao-avancado-2021/?referralCode=D1231C6B99B30C6EDF14)