Pick a workflow; the choice shapes everything
"Workflow" sounds soft, but it determines branch lifetimes, release cadence, conflict frequency, and how your CI is structured. Three patterns dominate and each fits a different team. The mistake is to mix them — half the team pretending it is GitFlow, half the team pretending it is trunk-based, with main commits arriving in two incompatible shapes. Pick one, document it, configure platform settings to enforce it.
GitHub Flow is the simplest: main is always deployable, every change happens on a short-lived feature branch off main, opens a PR, gets reviewed, lands via merge or rebase, deploys. No long-lived develop or release branches. Continuous deployment teams (most modern web/SaaS) use this because the cycle of branch → PR → merge → deploy fits in hours, not days. The implicit constraint: real CI/CD must work, otherwise "main is deployable" is a lie.
Trunk-Based Development goes further: most engineers commit to main directly (or via PRs that live for hours), feature branches are rare, and incomplete features hide behind feature flags. Releases happen multiple times per day. Used by teams optimizing for very fast feedback (Google, Spotify scale teams). Requires strong feature flags, comprehensive tests, and the cultural commitment that broken main blocks everyone — fixed within minutes.
GitFlow is the heaviest: main is production-only, develop is the integration branch, feature branches go off develop, release branches stabilize before a tagged release on main, hotfix branches go straight off main and merge into both. Used by teams shipping versioned products (desktop apps, libraries with semver, regulated software). The complexity buys reproducible release lines at the cost of overhead — bad fit for continuous deployment.