# Git Branching Strategies: GitFlow, GitHub Flow &amp; Trunk-Based Development

const relatedArticles = [
   slug: 'cron-jobs-tutorial', title: 'Cron Jobs Tutorial', description: 'Schedule tasks and automate your CI/CD pipeline.' ,
   slug: 'linux-file-permissions', title: 'Linux File Permissions', description: 'chmod, chown, and access control for dev environments.' ,
   slug: 'docker-for-developers', title: 'Docker for Developers', description: 'Containers, images, and Docker Compose for local development.' ,
]

  return (
    
      /* Schema.org JSON-LD */
      
      
      

      /* Breadcrumb Navigation */
      
        [Home](/)
        /
        [Blog](/blog/)
        /
        Git Branching Strategies
      

      /* Article Header */
      
        # 
          Git Branching Strategies: GitFlow, GitHub Flow &amp; Trunk-Based Development
        
        
          Git
          March 7, 2026
          12 min read
        
      

      /* Article Content */
      

        
          ## Why Branching Strategies Matter
          
            Every software team uses Git, but how you organize branches determines whether your workflow is a smooth highway or a merge-conflict minefield. A branching strategy defines how developers create, name, merge, and delete branches. The right strategy depends on your team size, release cadence, and deployment pipeline. The wrong one leads to integration nightmares, stale branches, and deployment fear.
          

          
            This guide compares the three most popular strategies -- GitFlow, GitHub Flow, and Trunk-Based Development -- with concrete examples, branch diagrams, and decision criteria so you can pick the one that fits your team.
          

        

        
          ## Strategy Comparison at a Glance
          
            
              
                
                  Feature
                  GitFlow
                  GitHub Flow
                  Trunk-Based
                
              
              
                Long-lived branchesmain + developmain onlymain only
                Feature branchesYes (days-weeks)Yes (hours-days)Optional (hours)
                Release branchesYesNoNo
                Hotfix branchesYesNo (use feature)No (commit to trunk)
                Merge strategyMerge commitsSquash merge / PRRebase / direct push
                Release cadenceScheduledContinuousContinuous
                Feature flags neededNoSometimesYes (critical)
                Best forVersioned software, mobile appsWeb apps, small teamsLarge teams, CD pipelines
              
            
          
        

        
          ## GitFlow: The Classic Enterprise Workflow
          
            GitFlow, introduced by Vincent Driessen in 2010, uses two long-lived branches (main and develop) plus three types of supporting branches: feature, release, and hotfix. It is designed for projects with scheduled releases and multiple versions in production.
          

          ### Branch Structure
          
            `main          ──●──────────────────●──────●──── (production releases)
                \\                  /      /
release/1.0    \\──●──●──────●    /       (stabilization)
                \\       \\    /   /
develop        ──●──●──●──●──●──●──●──── (integration branch)
                  \\  /       \\     /
feature/login   ●──●         \\   /
                           ●──●
                        feature/auth

Branch naming:
  feature/user-login
  feature/JIRA-123-payment
  release/1.2.0
  hotfix/critical-auth-fix`
          

          ### GitFlow Workflow Commands
          
            `# Start a new feature
git checkout develop
git checkout -b feature/user-dashboard

## Work on the feature... commit changes
git add .
git commit -m "Add dashboard layout with chart widgets"

## Finish feature -- merge back into develop
git checkout develop
git merge --no-ff feature/user-dashboard
git branch -d feature/user-dashboard

## Create a release branch when develop is ready
git checkout develop
git checkout -b release/1.2.0

## Fix bugs on the release branch, update version
git commit -m "Bump version to 1.2.0"

## Finish release -- merge into main AND develop
git checkout main
git merge --no-ff release/1.2.0
git tag -a v1.2.0 -m "Release 1.2.0"
git checkout develop
git merge --no-ff release/1.2.0
git branch -d release/1.2.0

## Emergency hotfix from main
git checkout main
git checkout -b hotfix/fix-payment-crash
## Fix the bug...
git checkout main
git merge --no-ff hotfix/fix-payment-crash
git tag -a v1.2.1 -m "Hotfix 1.2.1"
git checkout develop
git merge --no-ff hotfix/fix-payment-crash
git branch -d hotfix/fix-payment-crash`
          

          ### When to Use GitFlow
          
            - Mobile apps with app store review cycles (iOS, Android)
            - Desktop software with versioned releases (v1.0, v2.0)
            - Enterprise projects with QA/staging environments per release
            - Teams supporting multiple major versions simultaneously
          

          ### When to Avoid GitFlow
          
            - Web applications deployed continuously (too much ceremony)
            - Small teams under 5 developers (unnecessary complexity)
            - Projects without version numbers or scheduled releases
          
        

        
          ## GitHub Flow: Simple and Continuous
          
            GitHub Flow, popularized by GitHub itself, strips branching down to the essentials: one main branch, short-lived feature branches, pull requests, and continuous deployment. There is no develop branch, no release branches, and no hotfix branches. Every merge to main is deployed to production.
          

          ### The Complete Workflow
          
            `# 1. Create a feature branch from main
git checkout main
git pull origin main
git checkout -b add-search-filter

## 2. Make commits with clear messages
git add src/components/SearchFilter.tsx
git commit -m "Add search filter component with debounce"

git add src/hooks/useSearch.ts
git commit -m "Add useSearch hook with fuzzy matching"

## 3. Push and open a Pull Request
git push -u origin add-search-filter
## Open PR on GitHub -- triggers CI/CD checks

## 4. Code review + automated tests pass

## 5. Merge PR (squash or merge commit)
## GitHub merges and optionally deploys to production

## 6. Delete the branch
git checkout main
git pull origin main
git branch -d add-search-filter`
          

          ### Best Practices for GitHub Flow
          
            - **Keep branches short-lived** -- merge within 1-3 days. Longer branches accumulate merge conflicts and integration risk.
            - **Write descriptive PR titles** -- your PR title becomes the merge commit message. Make it meaningful for git log.
            - **Require CI checks before merge** -- set up branch protection rules to prevent merging broken code.
            - **Use squash merge for clean history** -- squash merge combines all PR commits into one clean commit on main.
            - **Deploy after every merge** -- if you are not deploying after every merge, GitHub Flow is not the right fit.
          
        

        
          ## Trunk-Based Development: The Speed-First Approach
          
            Trunk-Based Development (TBD) takes simplicity to its logical extreme: all developers commit directly to the main branch (the "trunk") or use very short-lived feature branches that last hours, not days. Google, Facebook, Netflix, and most high-performing engineering teams use TBD.
          

          ### How It Works
          
            `# Option A: Commit directly to main
git checkout main
git pull --rebase origin main
## Make small, focused changes
git add src/utils/format.ts
git commit -m "Add currency formatter with locale support"
git push origin main

## Option B: Very short-lived branch (merged same day)
git checkout main
git pull --rebase origin main
git checkout -b fix-date-parser
## Fix in 2-3 hours max
git add .
git commit -m "Fix date parser timezone offset bug"
git checkout main
git merge fix-date-parser
git push origin main
git branch -d fix-date-parser

## Feature flags for incomplete work
// config/features.ts
export const FEATURES = 
  NEW_DASHBOARD: process.env.FEATURE_DASHBOARD === 'true',
  BETA_SEARCH: process.env.FEATURE_SEARCH === 'true',

// In your component

function App() 
  return FEATURES.NEW_DASHBOARD
    ? 
    : 
`
          

          ### Prerequisites for Trunk-Based Development
          
            - **Comprehensive automated tests** -- every commit goes to production, so your test suite must catch regressions
            - **Feature flags** -- you need a way to deploy incomplete features without exposing them to users
            - **Fast CI/CD pipeline** -- builds must complete in minutes, not hours, to keep the trunk green
            - **Small, incremental commits** -- each commit should be independently deployable and safe
            - **Team discipline** -- no one commits code that breaks the build
          
        

        
          ## Branch Naming Conventions
          
            Consistent branch naming makes your repository navigable and your CI/CD rules predictable. Here are the most common conventions across all three strategies.
          

          
            
              
                
                  Type
                  Pattern
                  Examples
                
              
              
                Featurefeature/descriptionfeature/user-auth, feature/JIRA-456-search
                Bug fixfix/descriptionfix/login-redirect, fix/null-pointer
                Releaserelease/versionrelease/1.2.0, release/2026-q1
                Hotfixhotfix/descriptionhotfix/crash-on-login, hotfix/security-patch
                Chorechore/descriptionchore/update-deps, chore/ci-config
              
            
          
          
            Use lowercase, hyphens as separators, and include a ticket number if your team uses issue tracking. Validate branch names with a [regex pattern](/regex-tester/) like '(feature|fix|hotfix|release|chore)/[a-z0-9-]+' in a pre-push hook.
          

        

        
          ## Merge vs Rebase: Which to Use
          
            The merge-vs-rebase debate is one of the most common Git discussions. The answer depends on your branching strategy and what you optimize for: history clarity or traceability.
          

          
            
              
                
                  Aspect
                  Merge
                  Rebase
                
              
              
                HistoryPreserves full branch historyCreates linear history
                Merge commitsCreates merge commitNo merge commit
                Conflict resolutionOnce per mergePer rebased commit
                Safe for shared branchesYesNo (rewrites history)
                Best used forIntegrating feature into mainUpdating feature from main
              
            
          
          
            `# Golden rule: rebase to update, merge to integrate

## Update your feature branch with latest main
git checkout feature/search
git rebase main
## Resolve conflicts per commit if any

## Integrate feature into main (via PR or manual merge)
git checkout main
git merge --no-ff feature/search
## Creates a merge commit -- clear integration point

## Squash merge for cleaner history (GitHub PR option)
git checkout main
git merge --squash feature/search
git commit -m "Add search with fuzzy matching and filters"`
          
        

        
          ## Choosing the Right Strategy for Your Team
          
            Use this decision framework to pick the strategy that matches your team's reality, not its aspirations.
          

          
            
              
                
                  If your team...
                  Use
                  Reason
                
              
              
                Ships versioned releases (v1, v2)GitFlowRelease branches for stabilization
                Deploys web apps continuouslyGitHub FlowSimple, PR-based, CI/CD friendly
                Has 2-5 developersGitHub FlowMinimal overhead, easy to learn
                Has 50+ developers on one repoTrunk-BasedAvoids long-lived branch conflicts
                Deploys 10+ times per dayTrunk-BasedBranches add unnecessary latency
                Supports multiple prod versionsGitFlowParallel release/hotfix branches
              
            
          
          
            Many teams start with GitHub Flow and migrate to Trunk-Based Development as their CI/CD pipeline matures. GitFlow is less common in modern web development but remains the standard for mobile and desktop software with app store release cycles.
          

        

        
          ## Automating Branch Policies
          
            Branch protection rules enforce your strategy automatically. Here is an example GitHub Actions workflow that validates branch names and requires checks before merging.
          

          
            `# .github/workflows/branch-policy.yml
name: Branch Policy
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  validate-branch:
    runs-on: ubuntu-latest
    steps:
      - name: Check branch name
        run: |
          BRANCH=$ github.head_ref 
          if [[ ! "$BRANCH" =~ ^(feature|fix|hotfix|chore)/ ]]; then
            echo "Invalid branch name: $BRANCH"
            echo "Must start with feature/, fix/, hotfix/, or chore/"
            exit 1
          fi

      - name: Check PR size
        uses: actions/github-script@v7
        with:
          script: |
            const  data: files  = await github.rest.pulls.listFiles(
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: context.issue.number,
            );
            const changes = files.reduce((sum, f) =>
              sum + f.additions + f.deletions, 0);
            if (changes > 500) 
              core.warning(
                \`Large PR: $changes lines changed. Consider splitting.\`
              );
            `
          
          
            You can validate branch names, commit messages, and other patterns with a [Regex Tester](/regex-tester/) before hardcoding them into CI/CD configs. For [scheduled automation](/blog/cron-jobs-tutorial/) like stale branch cleanup, cron expressions handle the timing.
          

        

        
          ## Frequently Asked Questions

          
            
              What is the best Git branching strategy for small teams?
            
            
              GitHub Flow is ideal for small teams (2-10 developers). It uses a single main branch with short-lived feature branches that are merged via pull requests. There are no develop, release, or hotfix branches to manage. This simplicity reduces overhead while maintaining code quality through mandatory code reviews and CI/CD checks before merging.
            
          

          
            
              Should I use git merge or git rebase for feature branches?
            
            
              Use rebase for updating your feature branch with the latest main branch changes (git rebase main) to keep a linear history. Use merge (via pull request) when integrating the feature branch back into main, as this creates a merge commit that clearly marks when the feature was integrated. Never rebase branches that other developers have pulled -- this rewrites shared history and causes conflicts.
            
          

          
            
              What is Trunk-Based Development and when should I use it?
            
            
              Trunk-Based Development (TBD) is a strategy where all developers commit directly to the main branch (trunk) or use very short-lived feature branches lasting hours, not days. It requires feature flags to hide incomplete work, comprehensive automated testing, and a strong CI/CD pipeline. TBD is best for teams practicing continuous deployment with 10+ releases per day, such as Google, Facebook, and Netflix.
            
          
        

        /* CTA Section */
        
          ## Validate Your Git Patterns
          
            Test branch naming conventions, commit message formats, and CI/CD patterns with our free Regex Tester. Build and validate patterns directly in your browser.
          

          [
            Open Regex Tester
          ](/regex-tester/)
        

        /* Related Articles */
        
          ## Related Articles
          
            relatedArticles.map((article) => (
              
                ### article.title
                article.description

              
            ))
          
        

      
    
  )

---

*Originally published on [bytepane.com](https://www.bytepane.com/blog/git-branching-strategies/). Visit for free interactive calculators and tools.*
