O que é trunk based development? Guia para devs solo
Resumo
Trunk based development é um modelo de versionamento em que todo mundo integra mudanças pequenas na branch principal, a main ou trunk, pelo menos uma vez por dia. Branches curtas são aceitas, mas não branches que vivem semanas. Trabalho inacabado fica escondido atrás de feature flags, então a main continua pronta para deploy. Para devs solo e times pequenos, costuma reduzir conflitos e revisões gigantes. Exige testes confiáveis e um jeito rápido de reverter.
O que é trunk based development? É um modelo de branching em que todo mundo integra pequenas mudanças em uma única branch compartilhada, geralmente chamada de main ou trunk, pelo menos uma vez por dia. Se você usa branches, elas vivem horas, não semanas. Trabalho inacabado fica escondido atrás de uma feature flag, para que a trunk continue pronta para deploy a cada commit. A ideia é simples, e menos exótica do que o nome sugere.
Aqui vai a cena que deixa isso concreto. Você abre um projeto paralelo que largou há três semanas. A branch da feature está 41 commits atrás da main, dois arquivos têm conflito, e o que você estava construindo já não combina com o código ao redor. Trunk based development é o hábito que impede essa cena de acontecer.
O que trunk based development significa de fato
A referência trunkbaseddevelopment.com define o modelo como um fluxo de controle de versão em que os desenvolvedores colaboram em uma branch compartilhada e evitam outras branches de desenvolvimento de longa duração. Commits direto na trunk são aceitáveis para times muito pequenos. Pull requests também servem, desde que as branches de feature sejam curtas e nasçam do esforço de uma única estação de trabalho.
Três regras carregam a maior parte do peso.
Faça merge na trunk pelo menos uma vez a cada 24 horas.
Mantenha a trunk verde: um build quebrado na main é a prioridade de todo mundo.
Esconda trabalho incompleto com feature flags, em vez de guardá-lo em uma branch paralela.
Repare no que não aparece. Não há branch develop, nem branch de release longa por feature, nem uma fase de integração no fim em que todo mundo descobre que o código não encaixa. No modelo antigo, a dor é acumulada e paga de uma vez.

Por que isso vence branches longas para times pequenos
Branch longa é um empréstimo. Cada dia que ela vive, se afasta um pouco mais da main, e os juros aparecem como conflitos de merge, premissas desatualizadas e revisões que ninguém consegue terminar porque o diff toca 60 arquivos.
A página de capacidades sobre trunk based development do DORA associa essas práticas a melhor velocidade de entrega, estabilidade e disponibilidade, com base nos dados do State of DevOps. Mantenha no máximo três branches ativas no repositório. Faça merge na trunk ao menos uma vez por dia. Evite code freezes e fases de integração. São metas concretas e mensuráveis, o que é raro nessa área.
Para um dev solo ou um time de três pessoas, o argumento é ainda mais simples. Merges pequenos são fáceis de revisar, fáceis de reverter e fáceis de entender seis meses depois, quando você está olhando o git blame às 22h e tentando entender o que você pensava naquela época.
São três razões para fazer e uma para não fazer. As razões: diffs menores, feedback mais rápido do CI e uma main que você pode subir numa sexta-feira sem suar frio. A razão contra: se seus testes são fracos, fazer merge todo dia só espalha quebras mais rápido. Chegamos nisso adiante.
Branch curta ou commit direto na main?
As duas formas contam como trunk based development. A diferença está em quanta segurança você quer antes de o código entrar.
Commitar direto na main funciona quando você está sozinho ou em dupla, seu build local roda em menos de um minuto e você confia nos seus testes. É o ciclo mais rápido que existe. A maioria dos builders solo já faz isso sem chamar de nada.
Branches curtas com pull request fazem sentido quando uma segunda ou terceira pessoa entra no projeto, ou quando você quer que o CI rode em um checkout limpo antes do merge. A disciplina está na palavra curta. Uma branch que sobrevive ao dia seguinte já está indo na direção do modelo que você quer deixar.
Uma rotina prática que aguenta o tranco:
Atualize a main e crie uma branch com um nome que diga o que a mudança faz.
Faça a menor mudança que move as coisas para frente e rode o build completo localmente.
Abra o PR, deixe o CI rodar e faça o merge no mesmo dia.
Apague a branch. Não deixe elas se acumularem.
Se uma mudança não cabe em um dia, a resposta não é uma branch mais longa. A resposta é fatiar a mudança mais fino.
Como entregar trabalho incompleto sem quebrar a main?
É a pergunta que faz a maioria desistir. Se você faz merge todo dia, vai mesclar código de funcionalidades que ainda não existem para o usuário. Duas técnicas resolvem isso.
A primeira é a feature flag. O caminho novo de código entra no merge, mas desligado, então os usuários nunca o veem. Uma flag pode ser tão simples quanto um booleano em uma variável de ambiente:
const showNewCheckout = process.env.FEATURE_NEW_CHECKOUT === "true";
export function Checkout() {
return showNewCheckout ? <NewCheckout /> : <OldCheckout />;
}Para um projeto paralelo, isso basta. Quando você precisar de segmentação, rollouts graduais ou um kill switch sem novo deploy, um serviço gerenciado já se paga.
A segunda técnica é o branch by abstraction, para mudanças maiores, como trocar um cliente de banco de dados ou um provedor de pagamento. Você coloca uma interface na frente da implementação antiga, constrói a nova atrás da mesma interface, migra os chamadores aos poucos e só então apaga a antiga. Cada passo é um merge pequeno na trunk, e nada fica numa branch longa.

Uma ressalva honesta sobre flags: elas são dívida. Uma flag que fica no código por um ano é uma branch disfarçada. Dê a cada flag um responsável e uma data de remoção, e apague quando a funcionalidade estiver totalmente liberada.
O que seu CI precisa ter antes de tentar isso
Trunk based development sem rede de proteção é só quebra rápida. Três coisas precisam estar no lugar antes de você assumir o hábito de merge diário.
Um build que rode em todo push e termine em minutos, não em meia hora.
Testes que falhem quando algo real quebra. Número de cobertura importa menos do que pegar uma mudança ruim.
Um jeito rápido de reverter: fazer revert do commit ou desligar a flag.
Análise estática é uma camada extra barata. Ela pega uma classe de problemas, como bugs óbvios, cheiros de segurança e código duplicado, antes que um humano leia o diff.
Se você é o único revisor, ferramentas que apontam para pontos de risco ajudam ainda mais, porque ninguém mais vai avisar que o arquivo que você não para de tocar está virando uma bagunça.
Esqueça a ideia de que você precisa de um pipeline pesado no primeiro dia. Um único arquivo de workflow que instala, roda o lint, testa e faz deploy da main já é um bom começo. Testado, não ótimo, e vale fazer assim mesmo: é a primeira versão que funciona, e dá para apertar depois.
Release branches, hotfixes e o que ainda exige cuidado
Trunk based development não proíbe release branches. Alguns times criam uma branch a partir da trunk pouco antes de uma release, a estabilizam, publicam e apagam. Outros publicam direto da trunk e corrigem para frente quando aparece um bug. Para uma aplicação web publicada várias vezes por semana, corrigir para frente quase sempre é mais simples.
Apps mobile e qualquer coisa com revisão lenta nas lojas são outra história. Ali você pode manter uma release branch curta por versão, para corrigir o que já está nas mãos dos usuários. Mesmo assim, a regra vale: correções entram na trunk primeiro e depois são aplicadas por cherry-pick, nunca o contrário.
Hotfixes seguem a mesma lógica. Corrija na trunk, faça deploy, pronto. Uma branch de hotfix separada que nunca volta para a main é como times acabam com dois históricos divergentes.

Uma primeira semana realista
No primeiro dia, veja como seu repositório trabalha com branches hoje. Liste as branches abertas e anote a idade de cada uma. Tudo com mais de alguns dias é candidato a merge ou exclusão. Isso sozinho costuma mostrar onde está o atrito.
No segundo dia, adicione o mecanismo de flags. Mesmo uma variável de ambiente serve. Escolha uma funcionalidade em andamento, coloque o ponto de entrada atrás dela e faça merge do que já existe.
Do terceiro ao quinto dia, mude o hábito. Quebre cada tarefa em pedaços que caibam em um dia e faça merge de cada pedaço quando o CI passar. As primeiras partes vão parecer pequenas demais. Não são. Um commit que adiciona uma coluna de banco ainda não usada ou uma função sem chamadas é uma unidade de progresso perfeitamente válida, porque é segura, revisada e já integrada.
Ao final da semana você saberá duas coisas: se seus testes são confiáveis o bastante e quais partes do código resistem a mudanças pequenas. As duas são úteis, e nenhuma aparece enquanto você trabalha em branches longas.
Você não precisa de um dashboard para perceber. Observe quanto tempo suas branches vivem, com que frequência a main fica vermelha e quanto tempo uma mudança leva do primeiro commit até a produção. Se a idade das branches cai e os deploys ficam entediantes, o hábito está compensando.
Se você quer números sobre o efeito para o usuário do que sobe atrás de flags, uma ferramenta de experimentação consegue ligar um rollout a métricas reais, em vez de intuição.
Para um time de uma pessoa, um caderno simples também funciona. Anote o tempo entre merge e deploy toda semana durante um mês. A tendência diz mais do que qualquer número isolado.
Vale trocar, ou esperar?
Troque se você trabalha sozinho, em dupla ou em um time pequeno com testes em que confia pela metade e um CI que dá para melhorar. O custo de testar é uma semana de commits pequenos e um pouco desconfortáveis. O custo de ficar em branches longas se paga em conflitos e revisões lentas, e cresce a cada colaborador novo.
Espere se você não tem nenhum teste automatizado e nenhum jeito de reverter. Resolva isso primeiro, porque merges diários em uma trunk sem teste só mudam a dor de lugar.
Não é um método perfeito. É um método que funciona. Escolha a próxima pequena mudança do seu projeto atual, faça o merge hoje e veja como é. Qual é a menor fatia da funcionalidade atual que você conseguiria publicar antes de hoje à noite?