Introdução

O arquiteto de soluções e um de nossos especialistas @Ronaldo Ronie desenvolveu um artigo com intuito de expor uma abordagem de como trabalhar utilizando o git flow no processo de SCM de maneira simples e segura.

O SCM, ou Sistema de Controle de Código Fonte (do inglês Source Code Management), é um padrão utilizado por desenvolvedores de software para agilizar a criação e distribuição de códigos fontes em desenvolvimento.

Uma das principais vantagens dos sistemas SCM é o controle de versões, que permite a visualização do histórico das alterações efetuadas no código, possibilitando, assim, encontrar quando um determinado problema foi resolvido e o que foi alterado para o resolver.

Os sistemas de SCM como o GIT guardam os fontes separadas por “tags” e “branches”. Os tags representam versões onde o código que foi enviado para produção e branches onde o mesmo está em ativo desenvolvimento.

Normalmente, códigos guardados em tags não devem ser alterados, pois representam uma versão oficial do software naquele momento. Durante o processo de desenvolvimento, os fontes são enviados para as branches, que depois são juntadas (operação conhecida como merge) e viram uma tag.

Outra vantagem é sua flexibilidade, podendo operar utilizando regras de negócio (como filtros e restrições) ou até mesmo integrar outros sistemas externos, como um sistema de Integração Contínua (CI) ou um sistema de gestão de chamados/helpdesk.

Se você já trabalha com o GIT, como principal ferramenta de controle de versão, já deve ter visto várias abordagens de como utilizar e controlar branchs em um cenário de produção ou pessoal. Ou se você é novo com git, este fluxo irá te ajudar a ter maior familiaridade de como as empresas atuam nos projetos, utilizando fluxos de trabalho de maneira contínua.

 

Entendendo o SCM com GIT Flow

É muito comum vermos pessoas utilizando somente um branch para fazer commits em projetos pessoais. Isto não é errado, é muito tranquilo de se controlar tudo em uma branch quando se está desenvolvendo sozinho, mas o cenário muda bastante quando temos que interagir com mais pessoas, seja em um projeto opensource ou privado.

Nessas horas é de suma importância que se tenha total controle do que está sendo produzido por sua equipe, onde, ao mesmo tempo que, são corrigidas falhas, implementando novas funcionalidades, é importante ter o seu código de produção com total funcionamento para ser entregue ao seu cliente.

É nesse ponto que o git flow nos ajuda. Com a imagem abaixo é possível ter uma visão geral de como funciona esse fluxo.

 

 modelo organizacional

 

 

Então agora vamos entender como esse fluxo funciona. A branch master irá conter todo código já testado, versionado que será entregue ao cliente (em produção) e a develop é onde todo fluxo de desenvolvimento irá ocorrer antes de fazer o release versionado, que posteriormente será feito merge na master.

A branch develop deve sempre conter o código mais atual, onde as branchs de features serão ramificadas tendo ela como base. Por exemplo:  suponhamos que você precise criar um feature que mudará  interface de um componente, como faríamos esse processo?

Primeiro certifique-se de que a branch develop existe no seu repositório remoto listando suas branchs locais e remotas com o comando abaixo:

$ git branch -a

Caso não esteja, faça a sincronização do seu repositório remoto, fazendo o checkout criando sua branch develop e envie para seu repositório remoto, com o comando:

$ git fetch origin && git checkout -b develop && git push origin develop

Develop and Master Branches

 

 

Após ter criado a branch develop, que irá ser a branch base de todo desenvolvimento, é necessário criar a branch respectiva ao seu desenvolvimento, lembre-se de manter um padrão de nomenclatura para facilitar o entendimento como é sugerido no git flow (tipo-branch/nome-branch). No git flow existem os seguintes tipos de branchs:

 

feature: para novas implementações;

release: para finalizar o release e tags;

bugfix: para resolver um bug encontrado na realise que não foi para produção ainda;

hotfix: para resolver problema crítico em produção que não pode esperar novo release.

Para criar uma feature branch, devemos passar como prefixo do nome da branch o valor “feature/” seguido do nome da feature ou número da tarefa, caso exista, conforme comando abaixo:

$ git checkout -b feature/nova-feature

Após criado, você trabalha em sua modificação local, caso seja necessário, que outra pessoa trabalhe nesta mesma implementação, você deve compartilhar para seu repositório remoto executando o comando abaixo:

$ git push origin feature/nova-feature

Após implementação feita, agora é hora de fazer o merge desta feature com a branch develop, para isto, faça o checkout para a branch develop, realize o merge da feature e atualize o repositório remoto, com os comandos:

$ git checkout develop && git merge feature/nova-feature && git push origin develop

Feature Branches

 

Caso não ocorra nenhum conflito, estamos prontos para fazer o release desta implementação e submeter ao repositório remoto, para isto, crie a branch de release e envie para o repositório remoto com os comandos:

$ git checkout -b release/v1.0.1 && git push origin release/v1.0.1

Se for identificado algum bug durante o período de testes, após a criação da release, você deve tratar este bug criando uma branch do tipo bugfix.

$ git checkout -b bugfix/bug-name

Após realizar a correção, é necessário fazer o merge para a branch de release e para a branch de develop também, mantendo a branch develop sempre com as correções, evitando assim que erros reapareçam em produção após uma nova release.

$ git checkout release/v1.0.1 && git merge bugfix/bug-name && git push origin release/v1.0.1

$ git checkout develop && git merge bugfix/bug-name && git push origin develop

Após realizar todos os testes, e assegurar que o código pode ser enviado para produção, você deve fazer a tag da versão, com o comando:

$ git tag -a v1.0.1 -m “Release do novo componente”

 

Na hora de inserir a tag, gosto de utilizar tags anotadas, conforme o comando acima, pois ela registra informações de quem fez a tag com data, hash, caso não queira estas informações, simplifique utilizando o comando abaixo:

$ git tag v1.0.1

Agora vamos conferir se a tag foi criada e enviada para o repositório remoto:

$ git show v1.0.1 && git push origin v1.0.1

Se tudo correu bem, sua tag será criada e estaremos aptos a fazer o merge com a master deste pequeno release, para isto basta executar o comando abaixo.

$ git checkout master && git merge release/v1.0.1

Caso seja identificado um bug em produção, ou seja, após o merge ter sido realizado para a branch master, será necessário criar uma branch de hotfix, a partir da branch master. 

$ git checkout -b hotfix/bug-name

Depois de realizar a correção, deverá ser feito o merge para a branch master e criado uma nova tag, também é muito importante lembrar de realizar o merge para a branch de develop.

$ git checkout master && git merge hotfix/bug-name && git tag -a v1.0.2 -m “Release do novo componente hotfix” && git push origin master

$ git checkout develop && git merge hotfix/bug-name && git push origin develop

 

Hotfix Branches

 

Conclusão

Desta forma, temos um fluxo definido de todas as etapas do desenvolvimento, além de padronizar a nomenclatura das branchs, facilitando na hora de rastrear as alterações e todo o processo realizado.

Existe um plugin para facilitar a utilização do git flow exemplificado neste artigo, chamado git-flow, ele simplifica muitos dos comandos citados, realizando um conjunto de comandos do git em um único comando.

Resumindo, aprendemos como controlar nossas branch separadas por suas responsabilidades, não impactando na master que é onde nosso código estável se mantém fiel, utilizamos tags para versionar nossas releases e ter um controle bem mais flexível.