Comparação

Git Flow, GitHub Flow e trunk-based: qual Git workflow escolher

Atualizado: · Skillaria.Top

O Git Flow é um modelo de branches com as branches de longa duração main e develop e as auxiliares feature, release e hotfix; ele serve para produtos com versões planejadas. Para serviços web com deploys frequentes, costuma ser mais simples o GitHub Flow (branches curtas a partir da main e pull request) ou o trunk-based development com feature flags.

O que é um Git workflow e por que a escolha importa

Um Git workflow é um acordo do time sobre quais branches existem, de onde são criadas, para onde são mescladas e o que é considerado pronto para release. O próprio Git não impõe nada disso, então, sem um acordo, cada um trabalha do seu jeito e, um mês depois, o repositório tem dezenas de branches, ninguém sabe o que está em produção e os merges viram horas de conflitos.

Os modelos mais conhecidos são o Git Flow, o GitHub Flow (uma variante do Feature Branch Workflow) e o trunk-based development. Não se trata de "antigo e novo", e sim de ferramentas para condições diferentes: com que frequência você lança releases, quantas versões do produto mantém ao mesmo tempo e quão maduros são os testes automatizados.

Git Flow: o modelo com as branches develop e release

O Git Flow foi descrito por Vincent Driessen em 2010. O modelo se apoia em duas branches de longa duração:

  • main (em projetos antigos, master) — só código lançado; cada commit aqui corresponde a um release e recebe uma tag;
  • develop — branch de integração, onde entram as features prontas para o próximo release.

E em três tipos de branches temporárias:

BranchCriada a partir deMesclada emPara quê
feature/*developdevelopDesenvolver uma nova funcionalidade
release/*developmain e developEstabilizar a versão: correções, número de versão, documentação
hotfix/*mainmain e developCorreção urgente em uma versão já lançada

Git Flow com Git puro

O ciclo de uma feature e de um release fica assim:

# feature
git switch develop
git switch -c feature/cart-discounts
# ... commits ...
git switch develop
git merge --no-ff feature/cart-discounts
git branch -d feature/cart-discounts

# release
git switch -c release/1.4.0 develop
# ... ajuste de versão e correções ...
git switch main
git merge --no-ff release/1.4.0
git tag -a v1.4.0 -m "Release 1.4.0"
git switch develop
git merge --no-ff release/1.4.0
git branch -d release/1.4.0

A flag --no-ff é essencial neste modelo: ela cria um commit de merge mesmo quando um fast-forward seria possível, e assim o histórico mostra quais commits pertenciam a uma mesma feature ou release.

A extensão git-flow

Para não digitar essas sequências à mão, existe o utilitário git-flow (hoje normalmente se instala o fork mantido, que nos gerenciadores de pacotes costuma se chamar git-flow-avh). Ele adiciona subcomandos:

git flow init -d
git flow feature start cart-discounts
git flow feature finish cart-discounts
git flow release start 1.4.0
git flow release finish 1.4.0
git flow hotfix start 1.4.1
git flow hotfix finish 1.4.1

O git flow init pergunta os nomes das branches e dos prefixos (com -d aceita os valores padrão), e os comandos finish fazem todos os merges necessários, criam a tag e apagam a branch temporária. Muitos clientes gráficos do Git também trabalham com Git Flow por meio de botões.

Prós e contras do Git Flow

Prós: estrutura clara, status do código fácil de entender (main é o que está com os clientes; develop é a próxima versão), uma fase separada de estabilização do release e suporte prático a hotfixes. Isso combina bem com apps mobile, software instalável, bibliotecas e firmware — casos em que o release passa pela revisão da loja de apps ou é instalado no cliente.

Contras: muitas branches e merges, branches de feature de longa duração acumulam divergências com a develop, e os merges duplos de release e hotfix são fáceis de esquecer. Para um serviço web com vários deploys por dia, as branches de release viram burocracia. O próprio autor do modelo acrescentou em 2020 uma nota ao seu artigo: para software entregue continuamente, vale olhar abordagens mais simples, como o GitHub Flow.

GitHub Flow: branches curtas e pull request

O GitHub Flow é uma versão enxuta do Feature Branch Workflow. As regras cabem em poucos itens:

  1. A main está sempre funcionando e pronta para deploy.
  2. Todo trabalho é feito numa branch a partir da main, com um nome descritivo.
  3. A branch recebe push regularmente e abre-se um pull request (merge request) para discussão.
  4. Depois do review e do CI verde, a branch é mesclada na main.
  5. O que entra na main vai para produção imediatamente.
git switch main
git pull
git switch -c feature/new-payment
# ... commits com mensagens claras ...
git push -u origin feature/new-payment
# abrimos um pull request, passamos pelo review e pelo CI, mesclamos na main

Prós: uma única branch de longa duração, pouquíssimas regras, caminho rápido da ideia à produção, code review natural. Contras: não há um lugar previsto para manter várias versões nem para estabilizar antes do release e, sem bons testes automatizados, "a main está sempre pronta" fica só no desejo.

Uma abordagem parecida, com branches adicionais por ambiente (por exemplo, staging e production), às vezes é chamada de GitLab Flow. Ela é útil quando o deploy em produção não é instantâneo, mas sim programado ou feito após verificação manual.

Trunk-based development

No trunk-based development, todos os desenvolvedores integram as alterações numa única branch (o trunk, ou seja, a main) com frequência — pelo menos uma vez por dia. Se houver branches, elas vivem horas, não semanas. Funcionalidades inacabadas entram na main, mas ficam escondidas atrás de uma feature flag:

if (featureFlags.isEnabled("new-checkout", user)) {
    renderNewCheckout();
} else {
    renderOldCheckout();
}

A principal vantagem é a quase ausência de conflitos pesados: as alterações são pequenas e mescladas enquanto todos ainda lembram do contexto. O modelo pratica integração contínua no sentido literal e funciona bem para times maduros, com CI rápido e boa cobertura de testes. Branches de release são permitidas, mas são criadas a partir do trunk logo antes do lançamento, e as correções entram primeiro no trunk e depois são levadas via cherry-pick.

Contras: exige disciplina e infraestrutura — testes rápidos, flags, monitoramento. Para um iniciante, é assustador commitar na main todo dia, e um CI fraco transforma o trunk numa branch eternamente quebrada. As flags também precisam ser removidas a tempo, senão o código se enche de condicionais mortas.

Comparação entre Git Flow, GitHub Flow e trunk-based

CritérioGit FlowGitHub FlowTrunk-based
Branches de longa duraçãomain e developmainmain (trunk)
Vida da branch de featureDias e semanasDiasHoras ou sem branches
Frequência de releasesVersões planejadasA cada mergeContínua
Suporte a várias versõesSim, via tags e hotfixPouco práticoVia branches de release
Exigências de CI e testesMédiasAltasMuito altas
Risco de conflitos grandesAltoMédioBaixo
Curva de entradaÉ preciso aprender as regrasMínimaExige cultura e feature flags
Projeto típicoApp mobile, biblioteca, software instalávelServiço web, open source, startupProduto grande com deploys frequentes

Como escolher o git workflow do time

Responda a algumas perguntas:

  • Vocês precisam manter várias versões lançadas? Se há clientes na 2.x e na 3.x e as duas precisam de correções — Git Flow ou trunk-based com branches de release.
  • Com que frequência vocês fazem deploy? Uma vez por trimestre — o Git Flow não vai atrapalhar. Todo dia — escolha GitHub Flow ou trunk-based.
  • Quanto vocês confiam nos testes? Se o CI é lento e a cobertura fraca, comece com GitHub Flow com review obrigatório e vá encurtando as branches aos poucos.
  • Qual o tamanho e a experiência do time? Para um time pequeno e para iniciantes, o mais simples é o GitHub Flow: uma única regra, "a main está sempre funcionando", e pull request para tudo.

Dica prática: não adote o Git Flow "porque todo mundo usa". Comece pelo processo mais simples que resolve os seus problemas e só o complique quando surgir uma dor concreta — por exemplo, quando precisar de uma fase de estabilização ou de suporte a versões antigas.

Regras que funcionam em qualquer workflow

  • Proteja a main no servidor: proíba push direto, exija reviews e CI verde antes do merge.
  • Combinem os nomes das branches: feature/, fix/, hotfix/ mais o número da tarefa.
  • Mantenha as branches curtas: quanto mais tempo uma branch vive, mais doloroso é mesclá-la. Traga a main para a sua branch regularmente via merge ou rebase.
  • Escolha a estratégia de merge dos pull requests (merge commit, squash ou rebase) e use-a de forma consistente.
  • Marque os releases com tags anotadas, seguindo o versionamento semântico.

Hotfix em cada modelo: um bug, três processos

A diferença entre as abordagens fica mais visível numa correção urgente em produção.

No Git Flow, cria-se hotfix/1.4.1 a partir da main; depois da correção, a branch é mesclada na main com a tag v1.4.1 e obrigatoriamente na develop (ou na branch de release atual, se houver). Esquecer o segundo merge é um erro clássico: no release seguinte o bug "volta".

git switch -c hotfix/1.4.1 main
git commit -am "Corrigir cálculo do desconto"
git switch main && git merge --no-ff hotfix/1.4.1
git tag -a v1.4.1 -m "Hotfix 1.4.1"
git switch develop && git merge --no-ff hotfix/1.4.1

No GitHub Flow, o hotfix é uma branch curta comum a partir da main, com um pull request que ganha prioridade no review. Depois do merge, vai para produção pelo mesmo deploy automático; não existe um processo separado.

No trunk-based, a correção é commitada primeiro no trunk e, se houver uma branch de release em produção, o commit é levado para ela com git cherry-pick -x <hash>. A flag -x adiciona à mensagem uma referência ao commit original, para que a ligação fique visível no histórico. Se o problema estiver numa funcionalidade nova, muitas vezes basta desligar a feature flag dela, sem tocar no código.

Como responder na entrevista "qual Git workflow você usava"

O entrevistador não quer saber se você decorou os nomes, e sim se entende os trade-offs. Uma boa resposta: citar o modelo, descrever como funcionavam as branches e o review e explicar por que ele servia ao projeto. Por exemplo: "Usávamos GitHub Flow: branches a partir da main, pull request com review e CI obrigatórios e deploy automático depois do merge. Não adotamos Git Flow porque lançávamos várias vezes por semana e as branches de release só iam atrasar". Ponto extra: contar o que você mudaria se o processo crescesse.

Resumo

O Git Flow é um modelo rígido com as branches develop, release e hotfix, bom para produtos com versões planejadas e suporte a vários releases. O GitHub Flow é mais simples e serve para a maioria dos projetos web, enquanto o trunk-based development oferece a máxima velocidade, mas exige CI maduro e feature flags. Escolha o git workflow pela frequência de releases e pela qualidade dos testes, não pela moda. As três abordagens, com seus comandos e erros típicos, são trabalhadas na prática no curso de Git.

Perguntas frequentes

O Git Flow está ultrapassado?

Não, mas a área de aplicação dele encolheu. Para serviços web com deploy contínuo ele é excessivo, mas para apps mobile, bibliotecas e software instalável continua prático.

Preciso da branch develop se os releases são frequentes?

Normalmente não: a develop duplica a main e acrescenta um merge desnecessário. Com releases frequentes, bastam a main e branches de feature curtas.

Dá para usar rebase no Git Flow?

Dá para trazer a develop para a sua branch de feature pessoal ou ainda não enviada via rebase, mas os merges finais na develop e na main, no modelo clássico, são feitos com merge --no-ff para preservar a estrutura do histórico.

Por que uma feature flag é melhor do que uma branch de feature longa?

O código é integrado na main imediatamente e não diverge do resto da base, e ativar a funcionalidade vira uma decisão separada, que pode ser revertida sem reverter o código.

Como migrar do Git Flow para o GitHub Flow?

Conclua os releases em andamento, mescle a develop na main, reconfigure o CI para fazer deploy a partir da main e apague a develop. Crie as novas branches somente a partir da main.

Aprenda este tema em vídeo

Este tema é abordado em profundidade, com prática, no curso “Git do zero ao desenvolvedor confiante”.

Ir para o curso