Concept · Merging & history

Trunk-based development

Everyone merges small changes to main at least daily and hides unfinished work behind flags.

3 mintrunk-basedfeature flagsshort-lived branchesGitHub flow

In trunk-based development, everyone integrates into one shared branch, the trunk (usually main), at least once a day. Branches, if you use them at all, live for hours or a day or two, not weeks. main is always releasable.

text
main  ●──●──●──●──●──●──●──●──●──   (many small merges per day)
       \─●─/  \●/  \─●─/            (short-lived branches / PRs)

The opposite is long-lived feature branches merged at the end of a project, or GitFlow-style develop and release branches. Those defer integration, and the pain grows the longer you wait: big conflicts, surprise interactions, "merge week."

What makes it work

  • Small changes. Each PR does one thing and is reviewable in minutes. Large features land as a series of safe steps.
  • Fast CI on every change. If main is red, fixing it comes before any new work.
  • Feature flags. Unfinished code merges to main switched off:
go
if flags.Enabled(ctx, "new-checkout", user) {
	return newCheckout(ctx, cart)
}
return legacyCheckout(ctx, cart)

This separates deploying code from releasing a feature. You can turn the feature on for staff, then 5% of users, then everyone, and turn it off instantly if something goes wrong. See deployment strategies. The same switch serves graceful degradation.

  • Branch by abstraction for big rewrites: put an interface in front of the old implementation, build the new one behind it, switch over, then delete the old one. Every step merges to main.

Trade-offs

  • It requires discipline and automation. Without good tests and CI, integrating often only spreads breakage faster.
  • Flags are debt. Remove each flag once its feature is fully released, or the code fills up with branches nobody understands.
  • Not every context fits. Open-source projects with outside contributors, or products that ship several supported versions, may need longer-lived branches.

Where GitHub flow fits

GitHub flow (branch → PR → review → merge to main → deploy) is trunk-based development when the branches are short-lived. The rule that makes it trunk-based is how long branches live, not whether you use PRs.

Short branches also mean fewer merge conflicts and less need to rebase. The team workflows lesson compares the options.

Learn it in depth