Git Workflow para times e empresas!
Tags: github, workflow, productivity, programming
Published: 2021-06-14 19:35:47

## Introdução

Esse artigo tem como objetivo introduzir o Git WorkFlow de uma forma genérica, assim como estabelecer um padrão para mensagens utilizadas no versionamento. É de extrema importância que as orientações descritas neste documento sejam seguidas de forma **rígida** e **comprometida** pela equipe para um melhor funcionamento do projeto como um todo.

## Considerações iniciais

- Utilizamos o Git como nosso sistema de controle de versão;
- Nosso WorkFlow do repositório é baseado na ideia do [GitFlow](https://www.atlassian.com/br/git/tutorials/comparing-workflows/gitflow-workflow);
- Nosso fluxo de desenvolvimento envolve três branches que podem ser abstraídas como quatro etapas do desenvolvimento de uma atividade;
- Cada uma dessas branches tem o papel de refletir um ambiente de desenvolvimento.

![](https://media.giphy.com/media/SyP24XyDVsavNPECoR/giphy.gif)

## Git WorkFlow - Getting Started

Passo-a-passo das tecnologias e ferramentas necessárias para fluxo de desenvolvimento com Git:

1. Ter o Git instalado na sua máquina:
   Para saber se esta instalado, abra o CMD (tecla Win+R depois escreva CMD), execute o comando `git --version`, caso apareça a mensagem semelhante a esta:

![](https://i.imgur.com/a0og8Kq.png)

✔ Você pode prosseguir

Se não, procure instalar o [git](https://git-scm.com/book/pt-br/v2/Come%C3%A7ando-Instalando-o-Git) ou procure a equipe de Infra do seu serviço.

![](https://media.giphy.com/media/3cXmze4Y8igXdnkc3U/giphy.gif)

## Por que devemos usar o Git?

Antes de iniciar com o Git Flow, precisamos entender o "por quê?" da necessidade de se utilizar Git para controle de versões em um projeto. 

Primeiro iremos pensar em um projeto sem qualquer tipo de controle de versão (como SVN, Mercurial e etc.). Para que um desenvolvedor possa fazer alguma alteração no projeto que está em produção, ele irá precisar modificar diretamente o projeto principal ou fazer uma cópia do mesmo e, mais tarde, sobrescrever os arquivos antigos deste projeto. Neste caso, se duas pessoas (A e B) copiarem o projeto principal e depois ambas fizerem suas modificações em um mesmo arquivo, mais tarde, quando a pessoa A atualizar suas modificações no projeto principal, essas serão excluídas pelas modificações da pessoa B, pois ele irá sobrescrever as modificações de A, sem ao menos saber que haviam sido feitas. 

Em suma, não existe controle de versão e mesmo que, de alguma forma, se adotassem estratégias com os desenvolvedores em conjunto, o risco de se perder dados é muito grande! 

Quando utilizamos o Git a situação é melhorada exponencialmente, uma vez que o projeto está sendo versionado. Numa mesma realidade acima, em que A e B modificam um mesmo arquivo (que agora deve se encontrar em um repositório), agora com Git, quando a pessoa A inserir suas atualizações no projeto, estas serão aceitas sem problemas, mas quando a pessoa B for fazer a mesma coisa, ele deverá primeiramente baixar as atualizações do projeto, antes de realizar as suas modificações. Desta forma, nenhuma modificação realizada anteriormente será perdida e todos os desenvolvedores terão que adotar este processo. Existem casos em que será necessária a resolução de conflitos. Eles ocorrerão quando o desenvolvedor B, do caso acima, modificar a mesma linha do desenvolvedor A. O Git irá identificar que uma mesma linha foi modificada e ele não consegue interpretar qual seria linha correta, então antes de "subir" suas alterações, o desenvolvedor B deverá ver qual linha deve ser mantida, a sua, a de A, ou uma combinação das duas linhas, resolvendo assim o conflito gerado.

Ainda assim o projeto está sujeito a erros, podendo estes conflitos serem resolvidos erroneamente, sem o devido cuidado e códigos produzidos de maneira equivocada. Erros estes que poderão ser evitados se existir uma cultura de versionamento bem implementada. 

Todos os desenvolvedores que tiverem permissão para executar modificações nos códigos devem, obrigatoriamente, ter conhecimento de Git, para que não ocorram falhas. Este artigo irá abordar os padrões adotados para um versionamento de melhor qualidade atendendo as necessidades requisitadas pelo sistema da sua empresa.

![](https://media.giphy.com/media/kH6CqYiquZawmU1HI6/giphy.gif)

## O que é um Git WorkFlow ❓

![](https://wac-cdn.atlassian.com/dam/jcr:cc0b526e-adb7-4d45-874e-9bcea9898b4a/04%20Hotfix%20branches.svg?cdnVersion=1652)

O sistema de controle de versão Git trabalha com branches, que nada mais são do que ramificações (linhas independentes) de desenvolvimento nas quais podem se realizar modificações sem que isso afete a branch principal.

Um Git WorkFlow se trata de um padrão estabelecido para definição das interações necessárias entre diferentes branches em um projeto e bem como o seu gerenciamento.

Existem diversos modelos de Git WorkFlow como o GitLab Flow, GitHub Flow, GitFlow e etc. O Git Workflow adotado pelo versionamento deste texto é inspirado nos principais fluxos acima citados, sendo organizado da seguinte forma:

- **master**: É a nossa branch principal! Tenha CUIDADO ao se fazer modificações na mesma! Procure evitar qualquer modificação direta. É a
  branch que contém a versão mais estável do sistema, assim as modificações inseridas nessa branch poderão ser visualizadas no ambiente de produção. 
- **homolog**: Ambiente de validação para os clientes. Aqui temos as modificações que os clientes poderão validar e que já passaram pela validação dos devs. Qualquer sugestão de modificação deve então ser redirecionada aos gestores que então devem fazer um chamado para ser alterado na develop e então subido para homolog.
- **develop**: A branch de homolog abrigará todas as modificações que já foram testadas internamente pela empresa. Nesse caso, essa branch ainda pode conter modificações que ainda não foram validadas pelo cliente. As alterações que são inseridas nessa branch poderão ser visualizadas no ambiente de develop; Uma das branchs mais importantes, os desenvolvedores sempre trabalham em cima dessa branch.
- **feature**: A maior parte das branches serão criadas a partir da branch de **develop** e terão o nome de feature. A branch de feature deverá abrigar todas as modificações específicas da task. É a branch que contém as modificações que deverão ir para o ambiente de homolog.
- **test**: Existem algumas empresas que trabalham com testes, e muitas delas adotam uma branch única para esses casos, dividindo assim o serviço com um ambiente específico para testes.

![](https://media.giphy.com/media/cFkiFMDg3iFoI/giphy.gif)

## Comandos básicos do Git ✒️

Listando todas as branches contidas no seu repositório local:  `git branch`

![image-20201110163503614](https://i.imgur.com/CCCqWhF.png)

Verificar a branch atual selecionada e o status da sua working copy:  `git status`

![](https://i.imgur.com/JuUCkZH.png)

Atualizar as referências do repositório para as versões contidas no servidor:  `git fetch`

Trocar a Branch atual para outra: `git checkout <nome_branch>`

**OBS**: Sempre que for necessário selecionar uma branch que está apenas no servidor do repositório deverá ser executado anteriormente o comando: `git fetch`.

Atualizando o conteúdo de uma branch para o conteúdo do repositório remoto: `git pull`

Enviando o conteúdo de uma branch parar o repositório remoto: `git push origin <nome_branch_atual>`

Resetando o conteúdo de uma branch para o seu conteúdo do repositório remoto: `git reset --hard origin/<nome_branch_atual>`

## Nomenclatura de branches

As branches são nomeadas contendo os seguintes parâmetros:

Tipo da Tarefa / Número da sprint / Identificação do Work Item

### 1. Tipo da Tarefa

   - **feature**: indica que a branch criada deverá implementar alguma funcionalidade nova no sistema. 

     Ex.: ferramenta nova, adição de uma funcionalidade em alguma ferramenta. feature/S202104-1/ABC-1

   - **fix**: indica que a branch que deverá corrigir algum bug no sistema. 

     Ex.: problema na busca da ferramenta X. fix/S202104-1/ABC-1

   - **hotfix**: indica que a branch criada é uma branch que deverá corrigir algum bug rapidamente e que deve ser inserida no ambiente de produção o mais rápido possível. 

     Ex.: CSS que subiu errado para produção. hotfix/ABC-1

     

### 2. Número da Sprint

   Indica o número da Sprint do Work Item 

   Ex.: feature/S202004-1/ABC-1

   

### 3. Identificação do Work Item

   Identificação do código do Work Item 

   Ex.: feature/S202004-1/ABC-1

![](https://media.giphy.com/media/13UZisxBxkjPwI/giphy.gif)

## Padrão de mensagens (commits/merges)

### 1. Especificação para commits

Para uma melhor organização e posterior manutenção do sistema, adotaremos a padronização de mensagens de commit com base no [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) . A estrutura da mensagem de commit deve seguir o seguinte formato:

`<tipo> (escopo): <descrição`

- **tipo**: o tipo do commit segue a mesma lógica do tipo da tarefa descrito no tópico acima. Os tipos podem ser então: **feat**, **fix** e **hotfix**;
- **escopo**: o escopo indica o local onde foi feita a alteração. No caso da Empresa Fictícia ABC, será a ferramenta alterada. Caso seja mais de uma ferramenta poderão ser indicadas através de "/" e caso a ferramenta afetada possua sub ferramentas deverão ser indicadas através de ">";
- **descrição**: a descrição deve indicar qual foi a alteração feita no commit. Deve estar no tempo presente e descrever de forma objetiva a alteração feita.

Exemplos 

`feat(configuracaoInstituicao): adicionado botão que exibe detalhes da instituição`

### 2. Especificação para Merges/Pull Requests

   Para o preenchimento das mensagens de merge entre duas branches, por exemplo, entre sua feature branch e a branch test ou do título de criação de Pull Requests, é necessário que mensagem siga o padrão estabelecido:

 ` merge: <nome_branch> em <branch_de_destino>`

  Exemplos:
 `merge: fix/S202002-1/ABC-254 em homolog`
 ` merge: hotfix/support/ABC-3154 em test`

![]https://media.giphy.com/media/kH6CqYiquZawmU1HI6/giphy.gif()

# Mãos a obra!

## Configurando suas credenciais no git 

Para trabalhar no projeto é necessário configurar o email utilizado no git como o seu email da Empresa fictícia ABC.
`git config --global user.email <seu_email_abc_aqui>`

> Substitua o <seu_email_abc_aqui> pelo seu  email

![](https://media.giphy.com/media/TlK63EA6F1qRb7lll6M/giphy.gif)
## Clonando o repositório

Para trabalhar no projeto deverá ser criada uma cópia local do repositório que se encontra no servidor. Para isto deverá ser executado o comando git clone <url_do_repositorio>, no nosso caso:

`git clone https://git.empresaabc.com.br/apps/app-abc `

OBS: A partir do momento em que o repositório estiver na sua máquina não será mais necessário repetir este processo.

## Criando uma nova Branch

Criaremos uma nova branch para iniciar uma task, para isso, devemos cria-la acessando o site do seu gerenciador de tasks preferido ou utilizando o próprio github:

1. Para cada task deverá ser criada uma branch, através do Work Item do Jira/AzureDevops ou outra plataforma de monitoramento de tarefas para que o desenvolvimento seja realizado apenas nesta branch. Crie uma branch atrelada a esse card.
2. Preencha o campo name conforme o tópico citado acima e preencha informações relevantes para que o card seja ligado a branch sem falta de informação e de forma muito clara.

### Branches fix e feature

Caso a atividade seja independente de outras atividades em andamento, deverão ser criadas a partir da branch develop, seguindo o Fluxo descrito no tópico seguinte. Caso contrário, deverão ser criadas a partir da branch da atividade pai.

### Branches hotfix

Deverão ser criadas sempre a partir da branch master.

### Vamos lá!

Lembre-se sempre de clonar o repositório e confirmar se você está realizando o desenvolvimento na branch certa antes de começar a fazer modificações.

Agora que voce já clonou o repositório na pasta selecionada, vamos verificar se estamos na branch correta com o comando `git status`:

Caso não estejamos na branch correta, vamos nos mover para essa branch utilizando os comandos `git branch -a` para listar as branches existentes 

![](https://i.imgur.com/mRg27Co.png)

e o comando `git fetch` para baixar os objetos e referências que possam ter sido alterados do repositório. 

Por fim utilizaremos o comando `git checkout <nome_branch>` para trocar de branch, lembrando que o nome deverá ser trocado pelo nome da branch criada na sua plataforma de gerenciador de atividades.

Vamos checar mais uma vez em qual branch estamos:
`git status`

![](https://i.imgur.com/YTpMz1r.png)

Está na branch certa? Se sim! Mãos à obra !

...

Depois de codificar, mesmo que seja um pouco ou a task inteira, você deve "comitar" o que fez e enviar ao servidor, seguindo os comandos abaixo:

- **add** - adiciona os arquivos ou alterações que você fez no código para prepará-los para o commit. Utilize omando `git status` para verificar os arquivos alterados, ` git add <nome do arquivo>` para adicionar um arquivo específico ou `git add .` para adicionar todos os arquivos alterados.

- `git status`

  -  ![](https://i.imgur.com/YTpMz1r.png)

- `git add .`

  - ![](https://i.imgur.com/mYMnneO.png)

- commit - Após adicionar os arquivos modificados, necessitamos "comitar" os arquivos adicionados anteriormente, seguindo o padrão de mensagens
  de commit já descrito:

- `git commit -m "<mensagem_commit>"`

  - ![](https://i.imgur.com/tqEebjV.png)

    > OBS: procure realizar commits em blocos menores para que a descrição seja a mais breve e detalhada o possível.

- push - Pronto, estamos seguros e com todas as modificações adicionadas e "comitadas", agora precisamos enviar nossas modificações ao servidor,  com o comando `git push origin <nome_branch>`

  - ![](https://i.imgur.com/NlJTV2E.png)

Exemplo

`git push origin feat/S202102-1/ABC-254`

Após a finalização do desenvolvimento deverá ser seguido o respectivo fluxo relacionado a atividade finalizada.

![](https://media.giphy.com/media/hrRJ41JB2zlgZiYcCw/giphy.gif)
## Fluxo - feature/fix

Após o término do desenvolvimento, sua atividade deverá ser testada, aprovada e disponibilizada em produção. Para tal deverá ser seguido cada passo descrito abaixo:

1. Para disponibilização da modificação no ambiente de testes, será necessário fazer o merge da sua branch na branch de test (caso exista, se não será feita na develop mesmo).
2. `git checkout test`
3. `git pull origin test`
4. `git merge nome_branch --no-ff`
5. `git push origin test` 
6. Após feito o merge, será solicitado o preenchimento da mensagem do merge commit, utilizando o editor padrão do Git, que deverá ser preenchida conforme o tópico 2 da seção "**Padrão de mensagens (commits/merges)**". O editor padrão do Git é o [Vim](https://e-tinet.com/linux/editor-texto-vim/), logo caso não seja alterado o seu editor padrão, após o termino do merge será aberta uma janela do Vim, nela será mostrada um texto semelhante à `merge: feature/S10/TMX4 into test`, para alterar é necessário apertar o botão `i` e então alterar, para sair e salvar é necessário apertar `esc` e então `:wq`

7. Após a atividade ter sido testada e o work item ser movimentado para "DONE", será necessário criar um Pull Request (PR) dessa branch para a
   branch de homologação. O PR deverá ser criado para algum reviewer validar o código e aceitar o merge na branch de homolog.

- Ao abrir o PR, o title deverá ser preenchido conforme o tópico 2 da seção **"Padrão de mensagens (commits/merges)**"

- Preencha a descrição do seu PR com algo informativo e claro sobre o que será modificado.

- Para finalizar a criação do PR, clique no botão **Create**. (Ou similar)

4. Nesse momento, quando o reviewer validar o código, deverá ser sinalizado se a atividade em questão é uma atividade que precisa da validação do cliente. Caso seja necessário que o cliente valide essa alteração, o PR será aceito na branch de develop. 

5. Os PRs abertos para a homolog serão validados por pessoas específicas. Quando houver a necessidade de subir as modificações já validadas para a master, essas mesmas pessoas deverão abrir um PR da homolog para a develop.

  > OBS: A cada PR aceito para homolog, a branch feature/fix será deletada.


![](https://media.giphy.com/media/ely3apij36BJhoZ234/giphy.gif)

Parabéns ❗ 

Concluímos os fluxos do Git WorkFlow

Se você ficou se perguntando **Como vejo os commits contidaos na minha** **branch?** é simples, basta utilizar o comando ` git log`, este comando te mostrará em ordem cronológica descrescente os commits contidos na sua branch atual.

Para sair da visualização, aperte a tecla q reproduzindo o comando "quit".

Para acompanhar os commits e alterações de todo projeto, será mais fácil utilizar uma interface gráfica (IDE) ou utilizar o Azure DevOps na seção de Repositórios do projeto (Repos).

## Comandos para resolução de conflito

- Abortar um processo de merge:
  `git merge --abort`
- Resetar a branch para ficar idêntica ao do servidor e remover suas
  modificações:
  `git reset --hard origin/<nome da branch>`
- Resetar a branch para ficar idêntica ao do servidor e não remover suas
  modificações:
  ``git reset --soft origin/<nome da branch>`
- Resetar a branch para o seu último commit e remover suas modificações:
  `git reset --hard HEAD`
- Resetar a branch para o seu último commit e não remover suas
  modificações:
  `git reset --soft HEAD`
- Resetar a branch para o seu penúltimo commit e remover suas
  modificações:
  `git reset --hard HEAD^`

- Resetar a branch para o seu N-ésimo commit e remover suas modificações:
  `git reset --hard HEAD~N` (insira um valor para N, se for 2 por exemplo, ele irá resetar dois commits anteriores ao último)

![](https://media.giphy.com/media/fWgQH01z4rjwrZckyM/giphy.gif)
## Considerações

Não hesite em perguntar para o seu colega caso tenha alguma dúvida, depende somente de nós para seguir o padrão e termos um ambiente de
trabalho limpo e organizado!