Skip to content

Estratégia de Branches

Modelo de organização de branches para o desenvolvimento.

INSPIRADO EM GITFLOW

Nossa estratégia é inspirada no modelo Gitflow, mas com adaptações para nosso contexto.

NÃO usamos a ferramenta git-flow (comandos como git flow init).

Usamos Git nativo com branches organizadas seguindo conceitos do Gitflow.

O que é nossa Estratégia de Branches?

Um modelo que define como o código flui desde o desenvolvimento até a produção, usando branches organizadas por propósito.

Diferenças do Gitflow Original

Nossa estratégia tem adaptações:

Adicionamos branch fix/* (não existe no Gitflow original)
Flexibilizamos hotfix (pode ir pra develop/release, não só main)
Usamos Git nativo (não a extensão git-flow)
Adaptamos ao contexto (com/sem release conforme projeto)

Por que Inspirado em Gitflow?

  • Estrutura de branches clara (main, develop, feature, etc)
  • Conceito de branches temporárias vs permanentes
  • Fluxo bem documentado e conhecido na indústria

Mas fazemos do nosso jeito, adaptado à realidade do SENAI.


Estrutura de Branches

main (produção)

  ├─ release/v1.2.0 (preparação para produção)

develop (desenvolvimento ativo)

  ├─ feature/nova-funcionalidade (desenvolvimento)
  ├─ feature/outra-feature
  └─ fix/correcao-bug

hotfix/corrige-critico (correção urgente)

main (aplicado direto)

develop (sincronizado depois)

Variações do Flow

O Flow pode ser adaptado ao contexto do projeto. Não é "tudo ou nada".

Flow Completo (com Release)

Quando usar:

  • ✅ Projeto tem time de QA/Qualidade
  • ✅ Precisa homologação formal
  • ✅ Deploy não é automático
  • ✅ Projeto crítico (financeiro, saúde, etc)
  • ✅ Múltiplos devs trabalhando

Fluxo:

feature/* → develop → release/* → main

                      (QA testa)

Exemplo: Sistema de pagamentos, ERP, aplicações médicas


Flow Simplificado (sem Release)

Quando usar:

  • ✅ Dev sozinho ou dupla pequena
  • ✅ CI/CD robusto com testes automatizados
  • ✅ Deploy contínuo
  • ✅ Projeto interno simples
  • ✅ Sem necessidade de homologação formal

Fluxo:

feature/* → develop → main

         (CI/CD testa)

Exemplo: Ferramentas internas, protótipos, projetos pessoais


Main Recebendo de Develop (Exceção)

Em projetos com Flow Simplificado, main pode receber direto de develop:

bash
# MR direto
develop main (via MR, CI/CD passa)

Critérios para usar:

  • Pipeline CI/CD robusto
  • Testes automatizados confiáveis
  • Reversão rápida se necessário
  • Equipe pequena ou dev experiente

Nunca pular:

  • ❌ Merge Request (sempre obrigatório)
  • ❌ CI/CD (sempre precisa passar)
  • ❌ Aprovação (sempre necessária)

WARNING

Mesmo em Flow Simplificado, SEMPRE use MR. Nunca merge direto local.


Como Escolher?

CritérioFlow CompletoFlow Simplificado
Time de QASimNão
Tamanho do time3+ devs1-2 devs
CI/CDBásico ou manualRobusto e automático
CriticidadeAlta (financeiro, saúde)Baixa/Média
Frequência deploySemanal/QuinzenalDiária/Contínua
HomologaçãoFormalAutomática

Regra geral:

  • Dúvida? → Use Flow Completo
  • Pode simplificar depois se funcionar bem

Branches Principais

main - Produção

O que é:

  • Código em produção
  • Sempre estável
  • Cada commit = versão deployada ou deployável

Regras:

  • ❌ Nunca commitar direto
  • ❌ Nunca fazer merge local
  • ✅ Recebe de release/* ou hotfix/* (Flow Completo)
  • ✅ Recebe de develop via MR (Flow Simplificado)
  • ✅ Todo merge via MR
  • ✅ Sempre taggeado com versão (ex: v1.2.0)

Quem acessa:

  • Deploy automático (CI/CD)
  • Hotfix urgente (via branch específica)
  • Lead Técnico (casos extremos justificados)

develop - Desenvolvimento Ativo

O que é:

  • Branch principal de desenvolvimento
  • Próxima versão em construção
  • Integração contínua de features

Regras:

  • ❌ Nunca commitar direto
  • ❌ Nunca fazer merge local
  • ✅ Só recebe de feature/* ou fix/*
  • ✅ Todo merge via MR
  • ✅ Sempre atualizada e funcional

Fluxo:

bash
# Flow Completo
feature/* develop release/* main

# Flow Simplificado
feature/* develop main

Branches Temporárias

feature/* - Novas Funcionalidades

Quando usar:

  • Desenvolvimento de nova funcionalidade
  • Melhoria de feature existente
  • Qualquer mudança que adiciona valor ao produto

Nomenclatura:

bash
feature/nome-descritivo

Exemplos:
feature/crud-equipamentos
feature/login-google
feature/dashboard-vendas
feature/exportacao-relatorio

Ciclo de vida:

bash
# 1. Criar a partir da develop
git checkout develop
git pull origin develop
git checkout -b feature/nova-funcionalidade

# 2. Desenvolver com commits padronizados
git add .
git commit -m "feat(modulo): adiciona X"

# 3. Manter atualizada com develop (regularmente)
git checkout develop
git pull origin develop
git checkout feature/nova-funcionalidade
git merge develop

# 4. Finalizar: push + MR para develop
git push origin feature/nova-funcionalidade
# Abrir MR no GitLab: feature/* → develop

# 5. Após merge: branch deletada automaticamente

Boas práticas:

  • Criar feature branch para cada tarefa/issue
  • Manter branches pequenas e focadas
  • Fazer merge de develop regularmente (evita conflitos grandes)
  • Deletar após merge (automático no GitLab)

fix/* - Correções de Bugs

EXTENSÃO MODERNA

A branch fix/* não está no Flow original (que usa feature/* para tudo).

É uma extensão moderna adotada pela indústria por ser mais semântica e alinhar com Conventional Commits.

Quando usar:

  • Correção de bug em desenvolvimento
  • Bug encontrado em develop (antes de ir pra produção)

Diferença de hotfix/*:

  • fix/* → Bugs em desenvolvimento (develop)
  • hotfix/* → Bugs em produção (main)

Nomenclatura:

bash
fix/nome-descritivo

Exemplos:
fix/validacao-cpf
fix/calculo-desconto
fix/timeout-api
fix/upload-imagem

Ciclo de vida:

bash
# Igual a feature, mas com tipo "fix" nos commits
git checkout develop
git pull origin develop
git checkout -b fix/corrige-validacao

git add .
git commit -m "fix(formulario): corrige validação de CPF"

git push origin fix/corrige-validacao
# MR para develop

hotfix/* - Correções Urgentes em Produção

Quando usar:

  • Bug crítico em produção
  • Correção que não pode esperar próximo release
  • Problema de segurança

Nomenclatura:

bash
hotfix/nome-descritivo

Exemplos:
hotfix/corrige-falha-pagamento
hotfix/corrige-vazamento-dados
hotfix/corrige-login-quebrado

Ciclo de vida (DIFERENTE!):

bash
# 1. Criar a partir da MAIN (não develop!)
git checkout main
git pull origin main
git checkout -b hotfix/corrige-bug-critico

# 2. Corrigir com commits padronizados
git add .
git commit -m "fix: corrige bug crítico de pagamento"

# 3. MR para MAIN (urgente)
git push origin hotfix/corrige-bug-critico
# Abrir MR: hotfix/* → main

# 4. Após merge em main: TAG
git checkout main
git pull origin main
git tag -a v1.2.1 -m "Hotfix: corrige pagamento"
git push origin v1.2.1

# 5. Sincronizar com develop
# Abrir MR: main → develop

Fluxo visual:

hotfix/bug-critico
  ├─→ main (urgente, via MR) → TAG v1.2.1
  └─→ develop (sincronizar, via MR)

Importante:

  • Hotfix vai direto para produção
  • Depois sincroniza com develop (não pode esquecer!)
  • Pode flexibilizar DoD se muito urgente, mas documentar depois

release/* - Preparação para Produção

OPCIONAL

Release branches só são necessárias em Flow Completo.

Em Flow Simplificado, pule direto de develop para main.

Quando usar:

  • Preparar nova versão para produção
  • Últimos ajustes antes do deploy
  • Correções de bugs encontrados em homologação

Nomenclatura:

bash
release/vX.Y.Z

Exemplos:
release/v1.2.0
release/v2.0.0
release/v1.1.5

Ciclo de vida:

bash
# 1. Criar a partir da develop
git checkout develop
git pull origin develop
git checkout -b release/v1.2.0

# 2. Ajustes finais (apenas bugs, configs, docs)
# NUNCA novas features!
git add .
git commit -m "fix: corrige bug encontrado em homologação"
git commit -m "chore: atualiza versão para 1.2.0"

# 3. MR para main (produção)
git push origin release/v1.2.0
# Abrir MR: release/* → main

# 4. Após merge em main: TAG
git checkout main
git pull origin main
git tag -a v1.2.0 -m "Release 1.2.0"
git push origin v1.2.0

# 5. Sincronizar com develop
# Abrir MR: main → develop

O que pode fazer em release:

  • ✅ Corrigir bugs pequenos
  • ✅ Ajustar configs (versão, variáveis)
  • ✅ Atualizar documentação
  • ❌ NUNCA adicionar features novas
  • ❌ NUNCA mudanças grandes

Por que release existe?

  • Testa versão específica em homologação
  • Congela features (develop continua recebendo coisas novas)
  • Permite hotfixes mesmo durante release

Branches vs Conventional Commits

As branches têm tipo preferencial, mas não são limitadas a um tipo de commit.

Tipos Principais por Branch

BranchTipo PrincipalOutros Tipos Permitidos
feature/*featfix, docs, test, refactor, style, chore
fix/*fixtest, docs, refactor
hotfix/*fixdocs, chore (raramente)
release/*fix, chore, docsNUNCA feat ou refactor

Feature Branch - Múltiplos Tipos

Feature branch pode ter QUALQUER tipo de commit:

bash
# feature/relatorio pode ter:
feat(relatorio): adiciona estrutura base        ← Funcionalidade
feat(relatorio): adiciona filtros               ← Funcionalidade
fix(relatorio): corrige validação de datas      ← Correção
test(relatorio): adiciona testes unitários      ← Testes
docs(relatorio): atualiza README                ← Docs
refactor(relatorio): otimiza query              ← Refatoração
style(relatorio): ajusta formatação             ← Estilo
chore(relatorio): atualiza dependência          ← Manutenção

Por quê?

  • Feature é um "pacote" completo
  • Inclui código + testes + docs + ajustes

Release Branch - RESTRIÇÕES

Release branch TEM LIMITES claros:

bash
# ✅ PODE na release/*
fix: corrige bug encontrado em homologação
fix(api): corrige timeout em produção
fix(login): corrige validação de senha
chore: atualiza versão package.json para 1.2.0
chore: atualiza variáveis de ambiente
docs: atualiza CHANGELOG com mudanças da v1.2.0
docs: corrige typo em mensagem de erro

# ❌ NÃO PODE na release/*
feat: adiciona novo dashboard              # Feature nova = NÃO!
feat(user): adiciona campo telefone        # Mudança de feature = NÃO!
refactor: reorganiza toda estrutura        # Muito arriscado = NÃO!
perf: otimiza toda aplicação               # Mudança grande = NÃO!

Por quê release tem restrições?

  • Release = congelamento de features
  • Foco: estabilizar o que já existe
  • Só correções de bugs e ajustes finais
  • Mudanças grandes = risco alto

Regra Prática

Antes de commitar em release/*, pergunte:

  1. Isso é correção de bug encontrado em teste? → ✅ fix OK
  2. Isso é ajuste de config/versão? → ✅ chore OK
  3. Isso é correção de documentação? → ✅ docs OK
  4. Isso adiciona funcionalidade nova? → ❌ NÃO! Volta pra develop
  5. Isso muda código funcionando? → ❌ NÃO! Volta pra develop

Se dúvida:

  • Pequeno e seguro? → Pode
  • Grande ou arriscado? → Não pode

Fluxo Completo do Dia a Dia

Cenário 1: Desenvolver Feature Normal

bash
# 1. Atualizar develop
git checkout develop
git pull origin develop

# 2. Criar feature branch
git checkout -b feature/adiciona-relatorio

# 3. Desenvolver
# ... código ...
git add .
git commit -m "feat(relatorio): adiciona filtro por período"
git commit -m "feat(relatorio): adiciona exportação PDF"

# 4. Push e MR
git push origin feature/adiciona-relatorio
# GitLab: MR para develop

# 5. Após aprovação e merge: automático
# Branch deletada
# Pronto!

Cenário 2: Corrigir Bug em Desenvolvimento

bash
# 1. Criar fix branch da develop
git checkout develop
git pull origin develop
git checkout -b fix/calculo-errado

# 2. Corrigir
git add .
git commit -m "fix(vendas): corrige cálculo de desconto"

# 3. Push e MR
git push origin fix/calculo-errado
# GitLab: MR para develop

Cenário 3: Bug Crítico em Produção (Hotfix)

bash
# 1. Criar hotfix da MAIN
git checkout main
git pull origin main
git checkout -b hotfix/corrige-login

# 2. Corrigir urgente
git add .
git commit -m "fix: corrige timeout no login"

# 3. MR para main (URGENTE)
git push origin hotfix/corrige-login
# GitLab: MR para main
# Aprovação rápida

# 4. TAG após merge
git checkout main
git pull origin main
git tag -a v1.2.1 -m "Hotfix: corrige login"
git push origin v1.2.1

# 5. IMPORTANTE: Sincronizar com develop
# GitLab: MR de main para develop

Cenário 4: Preparar Release (Flow Completo)

bash
# 1. Criar release da develop
git checkout develop
git pull origin develop
git checkout -b release/v2.0.0

# 2. Ajustes finais
git commit -m "chore: atualiza versão para 2.0.0"
git commit -m "docs: atualiza CHANGELOG"
git commit -m "fix: corrige typo em mensagem"

# 3. Deploy em homologação e testa

# 4. MR para main
git push origin release/v2.0.0
# GitLab: MR para main

# 5. Após merge: TAG
git checkout main
git pull origin main
git tag -a v2.0.0 -m "Release 2.0.0"
git push origin v2.0.0

# 6. Sincronizar com develop
# GitLab: MR de main para develop

Sincronização de Branches

Manter Feature Atualizada com Develop

Por que?

  • Evita conflitos grandes no final
  • Pega correções de bugs recentes
  • Mantém branch funcional

Como fazer (regularmente):

bash
# Enquanto trabalha na feature
git checkout develop
git pull origin develop
git checkout feature/sua-feature
git merge develop

# Se houver conflitos, resolve e commita
git add .
git commit -m "chore: merge develop para manter atualizado"
git push origin feature/sua-feature

Quando fazer:

  • ✅ Diariamente (se develop muda muito)
  • ✅ Antes de abrir MR (sempre!)
  • ✅ Quando outra feature importante foi mergeada

Sincronizar Main → Develop

Quando?

  • Após hotfix em main
  • Após release em main
  • Sempre que main recebe algo que develop precisa

Como:

bash
# Opção 1: MR (recomendado)
# GitLab: Create MR de main para develop

# Opção 2: Merge local (se Lead permitir)
git checkout develop
git pull origin develop
git merge main
git push origin develop

Casos Especiais

Release com Bug - Corrigir na Própria Release

Cenário:

Dev A: feature/login → develop
Dev B: feature/cadastro → develop

Cria: release/v1.2.0

QA testa e acha bug em ambos!

Solução:

Dev A e Dev B corrigem NA PRÓPRIA RELEASE:

bash
# Dev A
git checkout release/v1.2.0
git pull origin release/v1.2.0

# Corrige o bug
git add .
git commit -m "fix(login): corrige validação encontrada em QA"

git push origin release/v1.2.0

# Dev B (mesmo processo)
git checkout release/v1.2.0
git pull origin release/v1.2.0  # Pega correção do Dev A

git add .
git commit -m "fix(cadastro): corrige campo obrigatório"

git push origin release/v1.2.0

Fluxo:

  1. QA encontra bugs
  2. Devs corrigem direto na release/*
  3. QA testa novamente
  4. Quando OK: release/* → main
  5. Depois: main → develop (sincronizar correções)

IMPORTANTE:

  • ❌ Não voltar para develop e refazer
  • ✅ Corrigir na release mesmo
  • ✅ Depois sincronizar com develop

Hotfix Durante Release (Caso Complexo)

Cenário: Você está preparando release/v1.2.0 com login + cadastro.

Enquanto isso:

  • Develop continua recebendo features (resetar-senha, novo-relatorio)
  • Bug crítico em produção! Precisa de hotfix urgente

Problema:

release/v1.2.0:  login + cadastro
develop:         login + cadastro + resetar-senha + novo-relatorio + HOTFIX
main:            (produção antiga) + HOTFIX

Como atualizar release com o hotfix SEM pegar as features novas?


Estratégia 1: Cherry-pick (Recomendado)

Pegar SOMENTE o commit do hotfix:

bash
# 1. Hotfix vai para main
git checkout main
git pull origin main
git checkout -b hotfix/corrige-pagamento

git add .
git commit -m "fix: corrige bug crítico de pagamento"
git push origin hotfix/corrige-pagamento

# MR: hotfix/* → main
# Após merge: anote o HASH do commit (ex: abc1234)

# 2. Main sincroniza com develop
# MR: main → develop

# 3. Cherry-pick na release
git checkout release/v1.2.0
git pull origin release/v1.2.0

# Pegar SÓ o commit do hotfix (use o hash)
git cherry-pick abc1234

# Se der conflito, resolve e continua
git add .
git cherry-pick --continue

git push origin release/v1.2.0

Resultado:

  • ✅ release/v1.2.0 = login + cadastro + hotfix
  • ✅ NÃO pegou resetar-senha nem novo-relatorio
  • ✅ QA pode continuar testando

Quando usar:

  • Hotfix é 1-2 commits específicos
  • Release está perto de finalizar
  • Não quer features novas na release

Estratégia 2: Recriar Release

Se muita coisa mudou ou cherry-pick ficou complexo:

bash
# 1. Abortar release atual
# (só se ainda não foi pra produção!)
git branch -D release/v1.2.0
git push origin --delete release/v1.2.0

# 2. Finalizar e mergear features importantes
# Garantir que login e cadastro estão OK em develop

# 3. Criar nova release do zero
git checkout develop
git pull origin develop
git checkout -b release/v1.2.1  # Versão nova

# Agora inclui: login + cadastro + hotfix
# E NÃO inclui: resetar-senha, novo-relatorio (ainda em dev)

Quando usar:

  • Release tinha muitos bugs
  • Mudou muita coisa no código
  • Cherry-pick muito complicado
  • Ainda dá tempo de refazer

Estratégia 3: Aceitar Features Novas (Raramente)

bash
# Merge completo de develop
git checkout release/v1.2.0
git merge develop
git push origin release/v1.2.0

# Agora release tem TUDO (incluindo features não planejadas)

Quando usar:

  • Features novas são pequenas e seguras
  • QA consegue testar tudo de novo
  • Prazo permite

Desvantagem:

  • ❌ Scope creep (release cresceu)
  • ❌ QA precisa testar mais coisas
  • ❌ Risco maior

Qual Estratégia Escolher?

SituaçãoEstratégia Recomendada
Hotfix simples (1-2 commits)Cherry-pick
Hotfix complexo + release longe de finalizarRecriar release
Release quase prontaCherry-pick
Muitas mudanças em developCherry-pick ou Recriar
Features novas são triviaisAceitar (com cuidado)

Regra de ouro:

Quando em dúvida, use cherry-pick. É mais seguro e controlado.


Várias Features em Paralelo

Sem problema! É exatamente para isso que Flow existe.

bash
# Dev 1
feature/crud-equipamentos develop

# Dev 2 (ao mesmo tempo)
feature/relatorio-vendas develop

# Dev 3 (ao mesmo tempo)
feature/integracao-api develop

Cada um trabalha independente, depois merge em develop via MR.


Feature Depende de Outra Feature

Opção 1: Esperar (recomendado)

bash
# Espera feature/A ser mergeada
# Depois cria feature/B da develop atualizada

Opção 2: Branch temporária da feature

bash
# Se MUITO urgente e não pode esperar
git checkout feature/A
git checkout -b feature/B

# Quando feature/A for mergeada:
git checkout feature/B
git rebase develop  # reescreve histórico

Versionamento Semântico

Gitflow funciona bem com Semantic Versioning:

vMAJOR.MINOR.PATCH

Exemplo: v1.2.3

Quando incrementar:

  • MAJOR (1.0.0 → 2.0.0): Breaking changes
  • MINOR (1.2.0 → 1.3.0): Nova funcionalidade compatível
  • PATCH (1.2.3 → 1.2.4): Correção de bugs

Exemplos:

bash
# Release com nova feature
release/v1.3.0 feat adicionado

# Hotfix
hotfix/v1.2.4 fix aplicado

# Breaking change
release/v2.0.0 mudança incompatível

Tags - Quando Criar?

Sempre que main recebe código:

bash
# Via release
release/v1.2.0 main
git checkout main
git pull origin main
git tag -a v1.2.0 -m "Release 1.2.0 - Adiciona login e cadastro"
git push origin v1.2.0

# Via hotfix
hotfix/corrige-pagamento main
git checkout main
git pull origin main
git tag -a v1.2.1 -m "Hotfix 1.2.1 - Corrige bug pagamento"
git push origin v1.2.1

Por quê?

  • ✅ Marca exatamente o que está em produção
  • ✅ Facilita rollback
  • ✅ Changelog automático
  • ✅ Rastreabilidade

Boas Práticas

1. Sempre Partir da Branch Correta

bash
# ✅ Correto
feature/* parte de develop
fix/* parte de develop
hotfix/* parte de main
release/* parte de develop

# ❌ Errado
feature/* parte de main
hotfix/* parte de develop

2. Branches Pequenas e Focadas

bash
# ✅ Bom: 1 feature por branch
feature/adiciona-login-google

# ❌ Ruim: múltiplas features
feature/adiciona-login-google-e-facebook-e-recuperacao-senha

3. Nomenclatura Clara

bash
# ✅ Bom
feature/crud-equipamentos
fix/validacao-cpf
hotfix/corrige-pagamento

# ❌ Ruim
feature/teste
fix/bug
minha-branch

4. Atualizar Regularmente

bash
# Pelo menos 1x por dia se develop muda muito
git checkout develop
git pull
git checkout sua-branch
git merge develop

5. Deletar Branches Antigas

bash
# GitLab deleta automaticamente após merge
# Se ficou branch local:
git branch -d feature/ja-mergeada

# Listar branches locais que não existem mais no remoto:
git remote prune origin

FAQ

Por que não commito direto em develop?

Porque precisamos de revisão via MR. Develop precisa estar sempre estável e funcional.

Posso criar feature a partir de outra feature?

Evite. Se necessário, espere a primeira ser mergeada. Se muito urgente, pode criar mas sincronize depois com rebase.

Quando usar fix/_ vs hotfix/_?
  • fix/* = bug em desenvolvimento (develop)
  • hotfix/* = bug em produção (main)
Preciso de release branch sempre?

Não. Se seu deploy é contínuo e automático (Flow Simplificado), pode fazer develop → main direto via MR. Release é para quando precisa "congelar" versão e testar em homologação.

E se eu fiz feature na branch errada?

Depende. Se commitou, pode fazer cherry-pick para branch correta. Se não, apenas mude de branch e commite lá.

Posso ter múltiplos hotfix ao mesmo tempo?

Sim, mas evite. Hotfix é urgente, resolve um e depois o próximo. Se tiver vários bugs urgentes, algo está errado no processo.

Quanto tempo deixo uma feature branch aberta?

Ideal: 1-3 dias. Máximo: 1 semana. Branches longas = conflitos gigantes.

Dev sozinho precisa seguir Flow?

Sim, mas use Flow Simplificado (sem release). Sempre use feature branches mesmo sozinho - facilita trabalhar em múltiplas coisas.

Main pode receber de develop direto?

Sim, em Flow Simplificado (projetos pequenos, CI/CD robusto). Mas sempre via MR, nunca merge local.

Como sei qual hash usar no cherry-pick?

Após fazer merge do hotfix em main, use git log para ver o hash do commit. Ou copie do GitLab na página do MR.


Referências externas:

Dúvidas?

Consulte o Lead Técnico ou canal #dev.

Documentação mantida pelo Time de Desenvolvimento 💪