Git Workflows Compared: Trunk-Based Development, GitFlow, and Ship/Show/Ask

The Branching Strategy Wars

Git workflows generate surprisingly passionate arguments. Some teams swear by GitFlow. Others call it overcomplicated and use trunk-based development. A few have settled on intermediate approaches like Ship/Show/Ask or GitHub Flow. The right choice depends on your team size, release cadence, and deployment infrastructure.

Trunk-Based Development

Everyone commits to main (or a short-lived feature branch that lives for at most a day or two). No long-running branches. No release branches. The trunk is always deployable.

# Typical trunk-based workflow
git checkout main
git pull
git checkout -b fix-login-bug     # Short-lived branch
# ... make changes ...
git push -u origin fix-login-bug
# Open PR, get review, merge to main
# Branch deleted immediately after merge

Requirements: You need strong CI/CD, feature flags for incomplete work, automated testing you trust, and the ability to deploy (or at least build) main at any time. If your team doesn't have these, trunk-based development will be chaotic.

Best for: Teams that deploy multiple times per day, SaaS products with continuous delivery, mature engineering organizations with strong testing culture. Google, Facebook, and Microsoft use trunk-based development at massive scale.

The catch: Feature flags add complexity. Managing dozens of active flags requires discipline and regular cleanup. And if your CI takes 45 minutes, a broken main blocks everyone.

GitFlow

GitFlow uses multiple long-running branches: main (production), develop (integration), feature/*, release/*, and hotfix/*. It was designed for software with scheduled releases and multiple supported versions.

# GitFlow branch structure
main          ─────●─────────────●──────  (production releases)
                   ↑              ↑
release/1.2  ─────●──────────────┘
                   ↑
develop      ──●──●──●──●──●──●──●─────  (integration)
               ↑     ↑     ↑
feature/foo  ──●─────┘     │
feature/bar  ──────────●───┘

Best for: Desktop software, mobile apps with App Store review cycles, products with multiple supported versions (v2.x and v3.x maintained simultaneously), regulated industries requiring release sign-off.

The downsides: Merge conflicts accumulate on long-lived feature branches. The ceremony of release branches adds overhead. For web applications deployed continuously, GitFlow is overkill — you're managing complexity that doesn't need to exist.

Honestly, I think GitFlow is the wrong choice for most web development teams in 2026. It was designed in 2010 for a different era of software delivery.

GitHub Flow

GitHub Flow is a simplified workflow: main is always deployable, and all work happens on feature branches that get merged via pull requests. No develop branch, no release branches.

main          ─────●────●─────●────  (always deployable)
                   ↑    ↑     ↑
feature/auth ──●───┘    │     │
feature/ui   ──────●────┘     │
fix/typo     ─────────────●───┘

This is what most small-to-medium teams actually use, even if they don't call it GitHub Flow. It's simple, works well with PR-based code review, and doesn't impose much process overhead.

Ship/Show/Ask

Rouan Wilsenach proposed this framework for classifying changes by how much review they need:

  • Ship — Merge directly to main without review. Typo fixes, config changes, dependency bumps you've tested locally. Requires trust and a strong CI pipeline.
  • Show — Merge to main, then open a PR for after-the-fact review. The work is already deployed, but teammates can give feedback. Used for straightforward changes where you're confident but want a second set of eyes eventually.
  • Ask — Open a PR and wait for review before merging. Used for complex changes, architectural decisions, or anything you're uncertain about.

I like this framework because it acknowledges that not all changes deserve the same process. Requiring a full PR review for fixing a typo in a README is waste.

Practical Recommendations

For a team of 2-5 developers shipping a web application:

  • Use GitHub Flow. Feature branches with PRs. Keep branches short-lived (1-3 days max).
  • If you can, adopt Ship/Show/Ask to reduce review bottlenecks for low-risk changes.
  • Deploy from main after every merge. If that scares you, invest in testing, not branching complexity.

For a team of 20+ working on a monorepo:

  • Trunk-based development with feature flags.
  • Short-lived branches (hours, not days) with required CI checks.
  • Invest heavily in test infrastructure and build speed.

For mobile apps or software with staged releases:

  • A simplified GitFlow — main, develop, and release branches. Skip the hotfix branch ceremony; just cherry-pick from main.

Whatever you choose, document it. A one-page "how we use Git" document prevents 80% of branching confusion on a team.