23 de outubro de 2026 | Jonas Mello

Gitflow: organizando branches, releases e hotfixes em um fluxo de trabalho

Entenda como o Gitflow organiza branches de feature, release e hotfix, como esse fluxo funciona na prática e em quais cenários ele ainda faz sentido — além de quando uma estratégia mais simples pode ser melhor.

Gitflow: organizando branches, releases e hotfixes em um fluxo de trabalho

Nos artigos anteriores, vimos os principais conceitos do Git e conhecemos o git worktree, que permite trabalhar com várias branches simultaneamente.

Mas quando várias pessoas começam a trabalhar no mesmo projeto surge outra questão:

como organizar todas essas branches?

Qual branch representa o código em produção?

De onde uma nova funcionalidade deve partir?

Onde devemos preparar uma nova versão?

E se aparecer um bug urgente em produção enquanto outras funcionalidades ainda estão sendo desenvolvidas?

Existem diferentes estratégias para organizar esse fluxo.

Uma das mais conhecidas é o Gitflow.

O que é Gitflow?

Gitflow é um modelo de organização de branches que define papéis específicos para diferentes tipos de desenvolvimento.

Em vez de simplesmente criar branches sem uma convenção definida, o Gitflow propõe uma estrutura semelhante a:

main
develop
feature/*
release/*
hotfix/*

Cada uma possui uma responsabilidade diferente.

De forma simplificada:

main
  │
  └── código publicado em produção

develop
  │
  └── integração das próximas funcionalidades

feature/*
  │
  └── desenvolvimento de novas funcionalidades

release/*
  │
  └── preparação de uma nova versão

hotfix/*
  │
  └── correções urgentes de produção

A ideia principal é criar um fluxo previsível para o desenvolvimento e publicação de versões.

As duas branches principais

No Gitflow tradicional existem duas branches de longa duração:

main
develop

main

A main representa o código oficialmente publicado.

Podemos imaginar:

main
  │
  ├── v1.0.0
  ├── v1.1.0
  └── v2.0.0

Em um projeto que segue Gitflow, não desenvolvemos funcionalidades diretamente nela.

Normalmente a main recebe código apenas quando:

  • uma nova versão é publicada;
  • um hotfix precisa corrigir produção.

Por isso, ela funciona como o histórico das versões oficiais do projeto.

develop

A develop representa o estado atual do desenvolvimento da próxima versão.

Novas funcionalidades normalmente partem dela e, quando concluídas, retornam para ela.

Podemos imaginar:

main
  │
  └── produção

develop
  │
  └── próxima versão

Assim, enquanto a main representa aquilo que já foi publicado, a develop representa aquilo que está sendo preparado para uma publicação futura.

Criando a branch develop

Se nosso repositório possui apenas a main, podemos criar:

git switch main
git pull
git switch -c develop
git push -u origin develop

Agora temos:

main
develop

E podemos começar a desenvolver funcionalidades a partir da develop.

Feature branches

Cada nova funcionalidade deve ser desenvolvida em sua própria branch.

Por convenção, é comum utilizar:

feature/nome-da-funcionalidade

Por exemplo:

feature/login
feature/dashboard
feature/recuperacao-senha

Diferentemente de alguns fluxos mais simples, no Gitflow essas branches normalmente nascem da develop.

Por exemplo:

git switch develop
git pull
git switch -c feature/login

Agora podemos trabalhar normalmente:

git add .
git commit -m "Adiciona formulário de login"

Nosso histórico poderia ficar assim:

main
  │
  A
  │
develop
  │
  B
   \
    C ── D
         │
    feature/login

Enquanto desenvolvemos a feature, outras funcionalidades podem existir em paralelo:

                 feature/login
                /
develop ───────●
                \
                 feature/dashboard

Cada funcionalidade permanece isolada.

Finalizando uma feature

Depois que a funcionalidade estiver concluída, ela deve retornar para develop.

Por exemplo:

git switch develop
git pull
git merge feature/login

Depois podemos remover a branch:

git branch -d feature/login

E, se necessário:

git push origin --delete feature/login

O fluxo fica conceitualmente assim:

develop
   │
   ├──── feature/login
   │          │
   │          │ commits
   │          │
   └──────────┘
       merge

Agora a funcionalidade faz parte da próxima versão que está sendo preparada.

Preparando uma release

Depois de algum tempo, a develop pode acumular várias funcionalidades:

develop
  │
  ├── login
  ├── dashboard
  ├── recuperação de senha
  └── novo perfil

Quando decidimos que esse conjunto de funcionalidades formará uma nova versão, podemos criar uma release branch.

Por convenção:

release/1.2.0

Criamos a branch a partir da develop:

git switch develop
git pull
git switch -c release/1.2.0

A partir desse momento, a release entra em uma fase de estabilização.

Normalmente não adicionamos grandes funcionalidades nela.

O objetivo passa a ser:

  • corrigir bugs;
  • ajustar documentação;
  • revisar configurações;
  • executar testes;
  • preparar a versão para publicação.

Enquanto isso, outras funcionalidades podem continuar sendo desenvolvidas na develop.

Conceitualmente:

                     feature/nova-funcionalidade
                    /
develop ───────────●───────────────
                   \
                    release/1.2.0
                         │
                         │ correções
                         │ testes
                         │ ajustes

Essa separação permite preparar uma versão sem interromper completamente o desenvolvimento da próxima.

Publicando a release

Quando a versão estiver pronta, a release precisa chegar à main.

Por exemplo:

git switch main
git pull
git merge release/1.2.0

Agora podemos marcar essa versão utilizando uma tag:

git tag -a v1.2.0 -m "Versão 1.2.0"

E enviar:

git push origin main
git push origin v1.2.0

Mas existe outro passo importante.

Durante a preparação da release podem ter sido feitas correções que também precisam continuar existindo no desenvolvimento futuro.

Por isso, a release também deve voltar para develop:

git switch develop
git merge release/1.2.0

Depois podemos remover a branch:

git branch -d release/1.2.0

O fluxo completo fica parecido com:

develop ────────────────●──────────────
              \        /
               \      /
            release/1.2.0
                 │
                 ↓
                main
                 │
               v1.2.0

E quando aparece um bug em produção?

Imagine que a versão:

v1.2.0

está em produção.

Enquanto isso, a develop já possui funcionalidades destinadas à próxima versão:

main
  │
 v1.2.0


develop
  │
  ├── nova tela
  ├── novo relatório
  └── nova integração

Agora descobrimos um bug crítico em produção.

Não podemos simplesmente publicar a develop, porque ela contém funcionalidades que ainda não estão prontas.

É exatamente para esse cenário que existe a hotfix branch.

Hotfix branches

Hotfixes são correções urgentes que partem diretamente da main.

Por convenção:

hotfix/descricao

ou:

hotfix/1.2.1

Criamos:

git switch main
git pull
git switch -c hotfix/1.2.1

Corrigimos o problema:

git add .
git commit -m "Corrige falha crítica no login"

Agora temos algo parecido com:

main ────────────────●
                      \
                       ●
                       │
                  hotfix/1.2.1


develop ─────────────────────────

A correção precisa seguir dois caminhos.

Primeiro, voltar para produção:

git switch main
git merge hotfix/1.2.1

Criamos uma nova tag:

git tag -a v1.2.1 -m "Versão 1.2.1"

E enviamos:

git push origin main
git push origin v1.2.1

Mas a correção também precisa fazer parte das próximas versões.

Portanto:

git switch develop
git merge hotfix/1.2.1

Depois:

git branch -d hotfix/1.2.1

Assim o bug não reaparece futuramente quando a próxima versão for publicada.

O fluxo completo do Gitflow

Podemos resumir o modelo assim:

                      feature/login
                     /             \
                    /               \
develop ───────────●─────────────────●───────
      \                                      \
       \                                      \
        \── release/1.2.0 ─────────────────────\
                         \                       \
                          \                       ↓
main ──────────────────────●─────────────────────●
                           │
                         v1.2.0
                             \
                              hotfix/1.2.1
                                  │
                                  ↓
                                v1.2.1

As regras principais são:

feature/*
   ↓
develop

develop
   ↓
release/*

release/*
   ↓
main + develop

hotfix/*
   ↓
main + develop

Esse é o modelo mental central do Gitflow.

Gitflow não é um recurso especial do Git

Existe uma distinção importante.

Gitflow é principalmente uma estratégia de organização de branches.

Tudo que vimos até agora pode ser feito utilizando comandos normais do Git:

git switch
git branch
git merge
git tag
git push

Ou seja, não existe nenhuma necessidade técnica de instalar uma ferramenta adicional para utilizar esse fluxo.

Podemos simplesmente adotar as convenções:

main
develop
feature/*
release/*
hotfix/*

e trabalhar normalmente.

A ferramenta git-flow

Também existe uma ferramenta chamada git-flow que automatiza várias dessas operações.

Depois de instalada, podemos inicializar o fluxo:

git flow init

A ferramenta pergunta quais branches e prefixos serão utilizados.

Normalmente encontraremos valores semelhantes a:

Production branch: main
Development branch: develop

Feature branches: feature/
Release branches: release/
Hotfix branches: hotfix/

Depois disso, vários fluxos podem ser executados através de comandos específicos.

Para iniciar uma feature:

git flow feature start login

Isso equivale conceitualmente a criar:

feature/login

a partir de develop.

Quando terminarmos:

git flow feature finish login

A ferramenta realiza as operações necessárias para concluir a feature.

Releases com git-flow

Para iniciar uma release:

git flow release start 1.2.0

Depois de concluir os ajustes:

git flow release finish 1.2.0

O git-flow automatiza as operações necessárias de merge e finalização previstas pelo modelo.

Hotfixes com git-flow

Para iniciar:

git flow hotfix start 1.2.1

Depois da correção:

git flow hotfix finish 1.2.1

Novamente, a ferramenta executa o fluxo esperado entre as branches.

Apesar da conveniência, é importante entender primeiro o modelo de branches.

Se entendemos o que feature, release, hotfix, develop e main representam, utilizar ou não a ferramenta git-flow passa a ser apenas uma escolha de automação.

Gitflow e Pull Requests

Em equipes, normalmente não fazemos os merges diretamente pelo terminal.

Em vez disso, podemos utilizar Pull Requests ou Merge Requests.

Uma feature poderia seguir:

develop
   ↓
feature/login
   ↓
commits
   ↓
push
   ↓
Pull Request / Merge Request
   ↓
code review
   ↓
merge em develop

O mesmo conceito pode ser aplicado às releases e hotfixes.

Assim conseguimos combinar o modelo de branches do Gitflow com:

  • revisão de código;
  • testes automatizados;
  • pipelines de CI/CD;
  • proteção de branches;
  • aprovações antes do merge.

Branches protegidas

Em projetos profissionais, normalmente é interessante impedir alterações diretas em branches importantes.

Por exemplo:

main
develop

podem ser configuradas como branches protegidas no GitHub, GitLab ou outras plataformas.

Isso permite exigir que mudanças passem por:

feature
   ↓
Merge Request
   ↓
testes
   ↓
revisão
   ↓
aprovação
   ↓
merge

Esse controle não faz parte do Gitflow em si, mas combina muito bem com o modelo.

Gitflow e Git Worktree

Aqui podemos conectar este artigo ao anterior.

Imagine que você está trabalhando em:

feature/dashboard

e precisa corrigir urgentemente algo em produção.

O Gitflow sugere criar:

hotfix/1.2.1

a partir da main.

E o Git Worktree permite manter as duas abertas ao mesmo tempo.

Por exemplo:

git worktree add -b hotfix/1.2.1 ../meu-projeto-hotfix main

Agora podemos ter:

meu-projeto/
    → feature/dashboard

meu-projeto-hotfix/
    → hotfix/1.2.1

Ou seja:

Gitflow organiza as branches.

Git Worktree organiza os diretórios onde podemos trabalhar nessas branches simultaneamente.

São conceitos diferentes, mas podem funcionar muito bem juntos.

As vantagens do Gitflow

O modelo pode funcionar especialmente bem quando existe um processo de releases claramente definido.

Entre seus benefícios estão:

  • responsabilidade clara para cada tipo de branch;
  • separação entre desenvolvimento e produção;
  • preparação explícita de releases;
  • fluxo específico para hotfixes;
  • facilidade para identificar versões publicadas;
  • possibilidade de continuar desenvolvendo enquanto uma release é estabilizada.

Em determinados tipos de projeto, essa previsibilidade pode ser bastante útil.

Mas Gitflow também tem custos

Gitflow adiciona várias branches e regras ao processo.

Isso significa que o time precisa lidar com:

main
develop
feature/*
release/*
hotfix/*

Além disso, funcionalidades podem permanecer separadas da branch principal durante bastante tempo.

Quanto mais tempo branches divergem, maior pode ser a chance de conflitos durante o merge.

Também existem mais operações de integração:

feature → develop

develop → release

release → main

release → develop

hotfix → main

hotfix → develop

Em equipes que publicam mudanças pequenas várias vezes por dia, toda essa estrutura pode acabar adicionando mais processo do que valor.

Gitflow ainda faz sentido?

Depende do projeto.

Gitflow pode continuar sendo útil em cenários onde existe uma noção clara de versões e ciclos de release.

Por exemplo:

v1.0
v1.1
v1.2
v2.0

especialmente quando uma versão precisa passar por um período próprio de estabilização antes de ser publicada.

Por outro lado, aplicações web modernas frequentemente trabalham com integração e entrega contínuas.

Nesse cenário, fluxos mais simples podem ser mais adequados.

Um exemplo é manter:

main
  │
  ├── feature pequena
  │        ↓
  │      merge
  │
  ├── próxima feature
  │        ↓
  │      merge
  │
  └── deploy contínuo

Essa abordagem reduz a quantidade de branches de longa duração e aproxima o desenvolvimento constantemente da branch principal.

Por isso, Gitflow não deve ser tratado como uma regra universal.

Ele é uma ferramenta de organização.

O melhor fluxo é aquele que resolve os problemas reais do projeto sem adicionar complexidade desnecessária.

Quando considerar Gitflow

Gitflow pode ser uma boa opção quando:

  • o projeto possui releases planejadas;
  • existe um período de estabilização antes de publicar uma versão;
  • diferentes versões precisam ser claramente identificadas;
  • é comum precisar corrigir produção enquanto a próxima versão continua em desenvolvimento;
  • o time se beneficia de regras explícitas sobre o papel de cada branch.

Para um projeto com deploy contínuo e pequenas mudanças frequentes, um fluxo mais simples provavelmente será suficiente.

O modelo mental mais importante

Não tente decorar todos os comandos.

Primeiro entenda o papel das branches:

                 nova funcionalidade
                        │
                        ↓
                    feature/*
                        │
                        ↓
develop ───────── próxima versão
   │
   ↓
release/* ─────── preparação da versão
   │
   ↓
main ──────────── produção
   ↑
   │
hotfix/* ──────── correção urgente

E lembre-se:

feature nasce de develop
feature volta para develop

release nasce de develop
release vai para main e develop

hotfix nasce de main
hotfix vai para main e develop

Se esse modelo estiver claro, os comandos utilizados para implementá-lo se tornam muito mais fáceis de entender.

Conclusão

Gitflow é uma estratégia de organização do desenvolvimento baseada em branches com responsabilidades bem definidas.

Seu modelo tradicional utiliza:

main
develop
feature/*
release/*
hotfix/*

A main representa as versões publicadas.

A develop reúne o desenvolvimento da próxima versão.

As feature branches isolam novas funcionalidades.

As release branches permitem preparar uma versão antes da publicação.

E as hotfix branches permitem corrigir rapidamente problemas encontrados em produção.

O modelo pode oferecer bastante previsibilidade para projetos que possuem ciclos de release bem definidos.

Mas essa organização também adiciona complexidade.

Para equipes que trabalham com integração e deploy contínuos, estratégias mais simples podem ser mais adequadas.

Por isso, talvez a principal lição sobre Gitflow não seja aprender todos os seus comandos.

É entender que branches também podem representar etapas do processo de desenvolvimento.

E, a partir daí, escolher conscientemente o fluxo que melhor se adapta ao projeto.

</> eKgSoftware, operação e experiência em notas práticas.