Concepts

GitHub Flow

Minimalist branching model designed for continuous deployment. Only two elements — main and feature branches — with PRs as the integration point and immediate deploy after merge.

evergreen#git#workflow#branching#dx#ci-cd

GitHub Flow is a simplified branching model created by GitHub in 2011 as a lightweight alternative to GitFlow. Its premise: main is always deployable, and every change goes through a Pull Request.

Why it exists

GitFlow was designed for software with scheduled releases. But for teams deploying multiple times a day, its multiple branches (develop, release/*, hotfix/*) add friction without benefit.

GitHub Flow reduces everything to the essentials:

main:     ──●────●────●────●────●──
              \  /  \  /  \  /
feature:       ●     ●     ●

The 6 rules

  1. main is always deployable — any commit on main can go to production
  2. Create a descriptive branch from mainfeature/add-login, fix/header-overflow
  3. Commit frequently to the branch — push early and often for backup and visibility
  4. Open a PR when you need feedback — don't wait until finished; draft PRs exist for this
  5. Merge only after review — at least one approval before merging
  6. Deploy immediately after merge — or even before (deploy from the branch)

Complete flow

# 1. Create branch from updated main
git checkout main
git pull origin main
git checkout -b feature/user-notifications
 
# 2. Work and commit
git add .
git commit -m "feat: add notification preferences UI"
git push -u origin feature/user-notifications
 
# 3. Open PR on GitHub
gh pr create --title "feat: user notifications" --body "Adds notification preferences"
 
# 4. Iterate based on review
git commit -m "fix: address review comments"
git push
 
# 5. Merge after approval (squash recommended)
gh pr merge --squash
 
# 6. Automatic deploy (CI/CD handles it)
# main → staging → production

When to use it

Ideal for:

  • Web applications with a single production environment
  • Teams practicing continuous deployment
  • Startups and small-to-medium teams
  • Projects where speed matters more than ceremonial control
  • SaaS, APIs, microservices

Consider alternatives when:

  • You need to maintain multiple versions in production (v1, v2, v3)
  • Releases require formal QA lasting several days
  • Packaged software with long release cycles
  • Regulations require strict release traceability

GitHub Flow vs GitFlow

AspectGitHub FlowGitFlow
Permanent branches1 (main)2 (main, develop)
Temporary branchesfeature/*feature/*, release/*, hotfix/*
ComplexityMinimalHigh
DeployContinuousPer release
HotfixesSame as featuresSpecial branch from main
Ideal forWeb apps, SaaSVersioned software, enterprise

Complementary patterns

Feature flags

Allow merging incomplete code to main without exposing it to users:

if (featureFlags.isEnabled('new-checkout')) {
  return <NewCheckout />;
}
return <LegacyCheckout />;

Benefits:

  • Smaller, more frequent PRs
  • Testing in production with selected users
  • Instant rollback without deploy

Branch deploy

Deploy the branch before merging to validate in a real environment:

# .github/workflows/branch-deploy.yml
on:
  pull_request:
    types: [labeled]
 
jobs:
  deploy-preview:
    if: github.event.label.name == 'deploy-preview'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./deploy-to-preview.sh

Conventional commits

Structure messages to generate automatic changelogs:

feat: add user notifications
fix: resolve header overflow on mobile
docs: update API documentation
chore: upgrade dependencies

Typical CI/CD

name: CI/CD
 
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
 
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test
      - run: npm run lint
 
  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build
      - run: ./deploy.sh

Anti-patterns

  • Giant PRs — hard to review, high risk. Split into small PRs.
  • Broken main — if main isn't deployable, the model collapses. CI is mandatory.
  • Long-lived branches — more than 2-3 days accumulates conflicts. Merge frequently.
  • Skipping review — direct merge to main without PR removes the safety net.
  • Manual deploy — if deploy isn't automatic, work piles up and risk increases.

Why it matters

GitHub Flow is the most widely adopted branching model for teams practicing continuous delivery. Its simplicity — a single main branch, short-lived feature branches, deploy after merge — eliminates the ceremony of more complex models like GitFlow and reduces the time between writing code and shipping it to production.

References

Concepts