Workflows#

How a team uses Git matters more than which tools they use. The major workflow patterns trade off between change isolation, integration frequency, and release cadence.

Trunk-Based Development#

Everyone commits to a single long-lived branch (main); short-lived branches if any. The 2026 default for most product teams; the merge pain is minimum, feedback is fast, and the branch is always ready to ship. Requires strong tests, feature flag discipline, and a small-change culture.

  • Small, frequent merges to main.

  • Feature flags for incomplete work that is on main but off in production.

  • Releases are tags or branches cut from main.

  • CI gates merges; the branch is always green.

        gitGraph
  commit id: "init"
  commit id: "feat-A"
  branch tiny-fix
  commit id: "fix"
  checkout main
  merge tiny-fix
  commit id: "feat-B"
  commit id: "feat-C"
  commit id: "feat-D"
  commit id: "v1.0" tag: "v1.0"
  commit id: "feat-E"
    

Strengths: minimum merge pain, fast feedback, the branch is always ready to ship. Weaknesses: requires strong tests, feature flag discipline, and small change culture. Works at scale (Google, Meta, Netflix).

The 2026 default for most product teams.

GitHub Flow#

A simple branch-and-merge model, probably the most common workflow on GitHub-hosted projects. Every change goes through a topic branch and a PR; CI gates the merge; main is always deployable. No explicit support for parallel release lines.

  • main is always deployable.

  • Create a topic branch for any change.

  • Open a PR; CI runs; review happens; merge to main.

  • Deploy main continuously or on cadence.

        gitGraph
  commit
  branch feature/login
  commit id: "scaffold"
  commit id: "happy path"
  commit id: "tests"
  checkout main
  merge feature/login
  commit id: "deploy"
  branch feature/profile
  commit id: "page"
  commit id: "validation"
  checkout main
  merge feature/profile
  commit id: "deploy"
    

Strengths: simple, well-supported by every platform. Weaknesses: no built-in story for parallel release lines.

Probably the most common workflow on GitHub-hosted projects.

GitLab Flow#

GitHub Flow plus environment branches. main is the integration branch; staging and production (or per- environment branches) receive promotions via merges from one to the next. Useful when deploys aren’t continuous and you want explicit promotion gates.

  • main is the integration branch.

  • staging and production (or per-environment) branches receive promotions.

  • Promote with merges from one to the next.

        gitGraph
  commit id: "init"
  branch staging
  commit id: "stage-base"
  branch production
  commit id: "prod-base"
  checkout main
  branch feature/x
  commit id: "feat"
  checkout main
  merge feature/x id: "merge"
  commit id: "more"
  checkout staging
  merge main id: "promote"
  checkout production
  merge staging id: "release" tag: "v1.0"
    

Useful when deploys aren’t continuous; replaces ad-hoc tagging with explicit branches.

GitFlow#

The 2010-era heavyweight. Two long-lived branches (main + develop) and three families of short-lived ones; explicit phases for versioned software releases. Outside of versioned products or libraries, most modern teams have moved away from GitFlow.

  • main, production releases.

  • develop, integration branch.

  • feature/*, release/*, hotfix/*, supporting branches.

  • Releases promoted via release branches; hotfixes branched from main.

        gitGraph
  commit id: "init"
  branch develop
  commit id: "dev start"
  branch feature/A
  commit id: "feat A"
  checkout develop
  merge feature/A
  branch feature/B
  commit id: "feat B"
  checkout develop
  merge feature/B
  branch release/1.0
  commit id: "release prep"
  checkout main
  merge release/1.0 id: "v1.0" tag: "v1.0"
  checkout develop
  merge release/1.0
  checkout main
  branch hotfix/1.0.1
  commit id: "hotfix"
  checkout main
  merge hotfix/1.0.1 id: "v1.0.1" tag: "v1.0.1"
  checkout develop
  merge hotfix/1.0.1
    

Strengths: explicit phases for software with versioned releases. Weaknesses: heavy ceremony, slow integration, prone to long-lived branches and painful merges.

Outside of versioned product or library releases, modern teams have mostly moved away from GitFlow.

Forking Workflow#

Each contributor has a personal fork; PRs come from forks rather than branches in the main repo. The default for open-source contributions because most contributors don’t have write access; required if maintainers want to keep the upstream branch list clean. For internal teams, branching in the same repo is simpler.

        sequenceDiagram
  participant U as Upstream Repo
  participant F as Your Fork
  participant L as Local Clone
  U ->> F: fork
  F ->> L: clone
  L ->> F: commit + push
  F ->> U: pull request
  Note over U: maintainer merges
  U ->> L: fetch upstream (sync)
    
  • The default for open-source contributions.

  • Required when contributors don’t have write access.

  • Adds a step (sync your fork) that some contributors miss.

For internal teams, branching in the same repo is usually simpler.

Pull / Merge Requests#

        sequenceDiagram
  actor Author
  participant Branch as Topic Branch
  participant CI as CI
  actor Reviewer
  participant Main as main

  Author ->> Branch: push commits
  Branch ->> CI: trigger pipeline
  CI -->> Author: green / red
  Author ->> Reviewer: open PR
  Reviewer ->> Branch: review
  Reviewer -->> Author: request changes / approve
  Author ->> Branch: address feedback
  Branch ->> CI: re-run
  CI -->> Reviewer: green
  Reviewer ->> Main: merge
    

Whatever the branch model, the PR is the unit of review and the place where most engineering judgment gets exercised. The discipline below is what separates a productive review culture from a slow one. Whatever the branch model, the PR is the unit of review.

  • Small, single concern, ~hundreds of lines max.

  • Self-explanatory, title and description tell the reviewer the why.

  • Tested, CI green; tests for the change exist.

  • Atomic commits, not always, but worth aiming for so each commit could ship independently.

  • Reviewable, prefer narrow diffs; refactors split from behavior changes.

Common conventions.

  • Conventional Commits (feat:, fix:, chore:) for changelog generation.

  • Required reviewers, one or two for normal changes; more for sensitive paths.

  • CODEOWNERS files to route review by area.

  • Auto-merge once green and approved.

Commit Hygiene#

The conventions that make commit history a readable artifact years later. Each rule below traces back to a specific failure mode; “what changed” without “why” is useless to your future self; tangled commits can’t be cherry-picked or reverted cleanly.

  • Imperative mood, “fix bug” not “fixed bug” or “fixes bug”.

  • Subject < 72 chars; body wraps at 72.

  • Why > what in the body; the diff already shows the what.

  • Reference issues in the body, not the subject.

  • One logical change per commit, when feasible.

Squash-merge or interactive-rebase before merging is fine; quality of main’s log matters more than perfect feature-branch hygiene.

Release Strategies#

How merges to main turn into actual releases. The four patterns below cover most teams; the right pick depends on how production tolerates change; internal tools can run continuous; library releases need versioning; mobile apps need cadence to match their submission process.

  • Continuous, every merge to main is a release. Requires strong tests and feature flags.

  • Cadence, release at a fixed cadence (weekly, biweekly).

  • Versioned, semantic versioning; each release is a tag plus release notes.

  • Release branches, cut from main, only critical fixes back-ported.

Pair with one of.

Monorepo vs. Polyrepo#

The two repository-structure philosophies. Both are professional choices. The choice often follows team structure (Conway’s Law again) more than any technical argument; what matters is whether the build tooling investment matches the choice.

  • Monorepo, one repo for many projects. Atomic cross-project changes, unified tooling, single CI. Heavy build tooling investment.

  • Polyrepo, one repo per project. Independent release cycles, smaller blast radius, simple CI.

Both are professional choices. The choice often follows the team structure (Conway’s law) more than a technical argument.

Common Pitfalls#

The five workflow mistakes that show up regardless of the branch model. Each one trades a small short-term convenience for a larger long-term cost, merge debt, broken collaborator work, lost bisect history, missed regressions, and the “urgent” changes that turn out to be exactly the riskiest.

  • Long-lived branches, merge debt grows; integrate often.

  • Force-pushing shared branches, breaks others’ work; use --force-with-lease and only on private branches.

  • Squash everything blindly, you lose the ability to bisect within a feature. Squash thoughtfully.

  • Living without CI on PRs, the workflow is broken without it.

  • Skipping reviews “just this once”, the riskiest changes most often have urgency attached.