The Great Code Branching Dilemma

Every engineering organization faces the same fundamental question: how do we balance speed with safety in our development workflow?

GitFlow promised us structure and predictability. Trunk-Based Development promised us velocity and simplicity. Yet most engineering teams I met find themselves caught in an uncomfortable middle ground, unable to fully embrace either approach.

The reality is that neither model fits the modern enterprise landscape. GitFlow’s heavyweight process throttles innovation. Trunk-Based Development’s minimal guardrails create anxiety among leadership and chaos among junior developers.

We need something that acknowledges the messy reality of enterprise development while still enabling the fast flow that modern businesses demand.

Why GitFlow Fails at Scale

GitFlow emerged from a different era of software development. When releases happened quarterly and teams were smaller, its elaborate branching ceremony made sense.

Today’s reality is different. Organizations ship (or wish to) multiple times per day. Teams include junior developers, contractors, and increasingly, AI-generated code. The traditional GitFlow model becomes a bottleneck rather than an enabler.

The problems are structural. Long-lived feature branches create merge conflicts that compound over time. Changes pile up into release cycles, preventing rapid delivery of critical fixes. Multiple staging areas create complexity without adding value. Risk grows and Quality control practices are reinforced to mitigate it.

Most damaging is the delayed feedback loop. By the time code reaches production, the original context has evaporated, the product team has moved to building the next feature. Issues that could have been caught early become expensive emergency fixes and the opportunity for iteration is lost.

The Trunk-Based Development Trap

Trunk-Based Development (TBD) swings the pendulum too far in the opposite direction. The promise is appealing: everyone commits to main, continuous integration catches issues early, and deployments happen frequently.

The reality is more nuanced. TBD requires exceptional discipline from every team member. A single poorly tested commit can break the entire team’s productivity. Junior developers feel pressure to commit incomplete code rather than delay integration.

Feature development becomes an exercise in creative gymnastics. Complex features must be developed incrementally without breaking existing functionality. Feature flags multiply, creating technical debt and configuration complexity.

Most importantly, TBD assumes a level of CI/CD maturity that many organizations haven’t achieved. When automated testing is incomplete or deployment pipelines are fragile, the lack of isolation becomes dangerous.

Introducing TBD++

TBD++ represents a middle path that acknowledges the realities of modern enterprise development. It combines the safety of branching and isolation with the velocity of continuous integration. The concept is to attempt to follow a natural feature development flow but behind the scenes leverage automation for all the heavy lifting necessary to guarantee all checks and balances that mitigate risk.

The core insight is simple: branches should be short-lived and purpose-built, but environments need their own deployment cadence. By implicitly creating temporary environment branches that act as integration points, we can maintain deployment flexibility without sacrificing code quality.

Every change starts as a branch from main. These branches are deliberately small, imagine on average a day of work. The constraint forces developers to think in deployable increments rather than monolithic features.

The magic happens in the integration flow. When a pull request is submitted, it automatically merges with the development environment branch, triggering a deployment. This provides immediate feedback without risking the main branch.

As the change progresses through testing and staging environments, it merges with corresponding environment branches. Each merge triggers automatic deployment and testing. The change branches is refreshed from main, preventing drift and reducing merge conflicts.

At a certain point in time, each environment holds the sum of the changes which have reached that maturity level but each change remains indepent.

The Flow in Practice

Consider a typical bug fix in TBD++. A developer creates a branch from main, implements the fix with appropriate tests, and submits a pull request. The submission triggers an automatic merge with the development branch and deployment to the development environment.

Code review takes place against a working deployment. Reviewers can see the fix in action, not just in abstract code. When the review is approved, the change automatically progresses to the test environment through a second implicit branch merge.

Testing teams work against a stable environment that includes only approved (by reviewer) changes. When testing passes, the change moves to staging for final acceptance. At each stage, automatic re-sync with the main branch ensures that conflicts are caught early.

The final merge to main happens only after all quality gates pass. Production deployment can be automatic or manual, depending on the business needs, e.g. IOT normally requires infrequent releases, API changes could have agreed dates with customers, etc.

All this is coupled with CI/CD pipelines which keep evolving to increasingly assess all the usual risks, main re-sync, linting, automated unit/functional/* tests, SAST, DAST, SCA, etc.

The Trade-offs

TBD++ isn’t a silver bullet. The approach trades simplicity for safety and flexibility.

The builds deployed to each environment haven’t been tested in their final form. This creates a gap between what’s tested and what’s deployed. Strong automated testing becomes even more critical.

Multiple environment branches can create resource overhead.

Teams must develop discipline around small, incremental changes. The process breaks down if developers try to cram large features into single branches. Cultural change is often harder than technical change.

When TBD++ Makes Sense

TBD++ works best for organizations caught between the extremes of GitFlow and Trunk-Based Development. Teams with mixed experience levels benefit from the additional safety nets. Organizations with complex deployment requirements appreciate the environment-specific progression.

The approach scales well with team size. Additional developers don’t create exponential complexity the way they might in pure TBD. The branch isolation provides natural coordination boundaries.

Regulated industries often find TBD++ appealing. The explicit quality gates and environment progression provide audit trails that compliance teams appreciate. The rollback mechanisms offer safety nets that pure TBD lacks.

Implementation Considerations

Success requires investment in automation and tooling. Teams should have mature CI/CD pipelines before attempting TBD++. Manual processes will create bottlenecks that negate the benefits.

Invest heavily in automated testing. The strategy’s safety depends on catching issues early in the pipeline. Unit test coverage should exceed 80%. Integration tests should cover critical user journeys.

Train teams on the disciplined approach to change size. Provide clear guidelines on what constitutes an appropriate branch scope. Code review should enforce these standards. Feature flags are also recommended.

The Path Forward

TBD++ represents an evolution in branching strategy thinking. Rather than choosing between speed and safety, it attempts to optimize for both within the constraints of enterprise reality.

The approach acknowledges that different types of changes need different treatment. Bug fixes can move quickly through the pipeline. Complex features may need more coordination. The tactics adapts to the work rather than forcing the work to adapt to the tactic.

As organizations continue to balance innovation with stability, hybrid approaches like TBD++ will become increasingly important. The key is finding the right balance for your specific context, team maturity, and business requirements.

The future of development workflows isn’t about finding the one true way. It’s about building systems that adapt to the complexity of modern software development while still enabling the fast flow that business demands.

Conclusion

Every branching strategy represents a set of trade-offs. TBD++ trades some simplicity for safety and flexibility. For organizations struggling with the GitFlow-versus-TBD dilemma, it offers a compelling middle path.

The approach isn’t right for every team or every situation. Pure TBD may work better for small, experienced teams with excellent tooling. GitFlow might still make sense for teams with infrequent releases and complex integration requirements.

But for the growing number of organizations caught between these extremes, TBD++ provides a framework for moving forward. It acknowledges the reality of mixed-skill teams, AI-driven development, complex deployment requirements, and the need for both speed and safety.

The ultimate test of any branching strategy is whether it enables teams to deliver value to customers quickly and safely. TBD++’s combination of short-lived branches, environment-specific progression, and automated quality gates aims to do exactly that.

The question isn’t whether TBD++ is perfect. The question is whether it’s better than the alternatives for your specific context. For many organizations, the answer may be yes.