Part 2: Branching Strategies and Workflows

Introduction

When I first started working with a team on a production TypeScript microservice, we didn't have a clear branching strategy. One developer would push directly to main, another would create feature branches with random names like my-changes or fix, and a third would work on a branch for weeks without merging. The result? Merge conflicts, broken deployments, and a lot of frustration.

After experiencing this chaos firsthand, I learned that choosing the right branching strategy is crucial for team productivity and code quality. In this part, I'll share the three main branching strategies I've used in production: Git Flow, GitHub Flow, and Trunk-Based Development—along with real examples of when each works best.

What Is a Branching Strategy?

A branching strategy is a set of rules and conventions that a team follows for creating, naming, and merging branches. It defines:

  • When to create branches

  • How to name branches

  • What types of branches exist

  • How and when branches get merged

  • Who can merge to which branches

Think of it as the "traffic rules" for your codebase—without them, you get chaos.

Git Flow: The Traditional Approach

Git Flow is a branching model created by Vincent Driessen in 2010. It's structured and comprehensive, designed for projects with scheduled releases.

Branch Types in Git Flow

1. Main Branches (permanent):

  • main (or master): Production-ready code

  • develop: Integration branch for features

2. Supporting Branches (temporary):

  • feature/*: New features

  • release/*: Prepare for production release

  • hotfix/*: Emergency production fixes

Git Flow Workflow

Here's how I used Git Flow when working on a scheduled-release e-commerce platform:

Starting a Feature

Completing a Feature

Creating a Release

Finishing a Release

Handling Hotfixes

Git Flow: Real-World Example

In my e-commerce project with quarterly releases:

Pros and Cons of Git Flow

Pros:

  • Clear separation between development and production code

  • Excellent for scheduled releases (quarterly, monthly)

  • Hotfixes can be deployed without deploying unfinished features

  • Well-documented and widely understood

Cons:

  • Complex with many branches to manage

  • Overhead for continuous deployment scenarios

  • Merge conflicts can be frequent

  • Not ideal for fast-moving projects

When I Use Git Flow:

  • Projects with scheduled release cycles

  • Products requiring extensive QA/testing before release

  • Teams with dedicated release managers

  • When production stability is critical

GitHub Flow: Simplified for Continuous Deployment

GitHub Flow is a lightweight branching strategy created by GitHub. It's designed for teams that deploy continuously.

The Simple Rules

  1. main branch is always deployable

  2. Create descriptive feature branches from main

  3. Commit to your feature branch and push regularly

  4. Open a Pull Request when ready

  5. After review and CI passes, merge to main

  6. Deploy immediately after merging

GitHub Flow Workflow

This is my preferred workflow for microservices with continuous deployment:

Working on a Feature

Creating a Pull Request

On GitHub:

  1. Click "Compare & pull request"

  2. Write clear description:

  1. Request reviews from team members

  2. Ensure CI/CD checks pass

Merging and Deploying

GitHub Flow: Real-World Example

In my TypeScript microservices with CI/CD:

Branch Protection Rules on GitHub

For GitHub Flow, I set up these protections on main:

Pros and Cons of GitHub Flow

Pros:

  • Simple and easy to understand

  • Perfect for continuous deployment

  • Fast iteration and deployment

  • Minimal overhead

  • Great for small to medium teams

Cons:

  • No dedicated release branches

  • Harder to maintain multiple versions

  • Requires robust CI/CD and testing

  • Not suitable for scheduled releases

When I Use GitHub Flow:

  • Microservices with continuous deployment

  • Web applications deployed multiple times per day

  • Teams practicing DevOps/SRE

  • When speed of delivery is critical

Trunk-Based Development: Modern CI/CD Approach

Trunk-Based Development (TBD) is a branching strategy where developers work in short-lived feature branches (or directly on trunk) and merge frequently to a single branch called "trunk" (usually main).

Core Principles

  1. Short-lived branches: Feature branches live for hours or days, not weeks

  2. Frequent integration: Merge to trunk at least daily

  3. Feature flags: Hide incomplete features behind toggles

  4. Comprehensive automated testing: Trust in CI/CD pipeline

  5. Small, incremental changes: Avoid large batches

Trunk-Based Development Workflow

Here's how I implement TBD in a high-velocity TypeScript API:

Small, Frequent Changes

Using Feature Flags

Enabling Features Gradually

Trunk-Based Development: Real-World Example

In my payment processing microservice:

All changes are in production immediately, but feature is controlled via flags.

Pros and Cons of Trunk-Based Development

Pros:

  • Fastest integration and feedback

  • Minimal merge conflicts

  • Forces small, incremental changes

  • Excellent for high-performing teams

  • Natural fit for continuous deployment

Cons:

  • Requires excellent test automation

  • Needs mature CI/CD pipeline

  • Requires feature flag infrastructure

  • Can be intimidating for new developers

  • Incomplete features in production code (mitigated by flags)

When I Use Trunk-Based Development:

  • High-velocity teams with strong testing culture

  • Microservices with robust CI/CD

  • When deploying multiple times per day

  • Teams practicing DevOps/SRE

  • When feature flags infrastructure is in place

Choosing the Right Strategy

From my experience, here's how to choose:

Git Flow

Choose when:

  • Scheduled releases (quarterly, monthly)

  • Multiple versions in production (e.g., mobile apps)

  • Extensive manual QA required

  • Traditional enterprise environment

Example: Enterprise e-commerce platform with quarterly releases

GitHub Flow

Choose when:

  • Continuous deployment to single environment

  • Web applications or APIs

  • Small to medium team size

  • Good automated testing coverage

Example: SaaS web application with daily deployments

Trunk-Based Development

Choose when:

  • High-velocity continuous deployment

  • Mature CI/CD and testing infrastructure

  • Feature flag system available

  • Experienced development team

Example: Microservices architecture with multiple deployments per day

Branch Naming Conventions

Regardless of strategy, use clear naming conventions:

My Standard Convention

Naming Best Practices

Working with Pull Requests

My Pull Request Workflow

1. Keep PRs Small and Focused

2. Write Descriptive PR Descriptions

3. Request Specific Reviewers

Handling Merge Conflicts

Conflicts are inevitable. Here's how I handle them:

Practical Tips from Experience

1. Pull Before You Push

2. Push Frequently

3. Commit Often, Push Less Often

4. Rebase to Keep History Clean (Advanced)

Warning: Only rebase branches that you own and haven't been shared with others.

Conclusion

Choosing the right branching strategy is crucial for team productivity and code quality. In this part, we covered:

  • Git Flow: Traditional approach with multiple branch types, perfect for scheduled releases

  • GitHub Flow: Simplified workflow for continuous deployment

  • Trunk-Based Development: Modern approach with short-lived branches and feature flags

  • Branch naming conventions and PR best practices

  • Handling merge conflicts and practical tips

From my experience:

  • Start with GitHub Flow if you're unsure—it's simple and effective

  • Move to Trunk-Based Development as your testing and CI/CD mature

  • Use Git Flow if you have scheduled releases and need separation between development and production

In Part 3, we'll explore Monorepo vs Polyrepo strategies, examining real-world examples from microservices projects and discussing how to choose between these architectural approaches.


Key Takeaways:

  • Branching strategy must match your deployment frequency

  • Small, focused PRs are easier to review and merge

  • Automate everything you can (CI/CD, testing)

  • Feature flags enable trunk-based development

  • Good commit messages and branch names improve collaboration

Remember: The best branching strategy is the one your team actually follows!

Last updated