One branching strategy for many teams Jump to heading
In separate repositories, each team picks its own branching model and nobody else notices. In a monorepo, everyone shares one main, one set of branch protections and one merge queue, so a choice that suits one team is imposed on all of them. A team that deploys hourly cannot share a GitFlow develop branch with a team that releases quarterly; a team that wants linear history collides with one that relies on merge commits. The way through is to separate what must be shared from what can vary. The trunk, the merge rules and the quality bar must be common. Release cadence, release branches and deployment can vary by team, attached to paths rather than to the whole repository. This page lays out that split, within monorepo branch topology.
When to use this approach Jump to heading
- Several teams share a monorepo and disagree about the branching model.
- Some teams deploy continuously and others release on a schedule.
- Repository-wide rules — branch protections, merge methods — were chosen for one team and frustrate others.
- You are consolidating repositories into a monorepo, as in merging two repositories while keeping history.
Step 1 — Decide what must be shared Jump to heading
Some things can only exist once in a repository. List them and agree them across teams first, because every other decision builds on them.
# Shared (decided once, for everyone)
- One trunk: `main`. All work merges there through pull requests.
- One merge method: squash. One merge queue on `main`.
- Required on main: build and tests of affected projects, lint, signature check.
- Short-lived branches; long-lived branches only with an owner and a sync plan. Step 2 — Give teams ownership of paths, not branches Jump to heading
In a monorepo, ownership attaches naturally to directories. Code owners for each team’s paths decide reviews; affected-project CI decides which checks run. Teams then control their own area without needing their own branches.
# CODEOWNERS
/services/billing/ @acme/billing
/services/export/ @acme/data-platform
/apps/web/ @acme/web
/libs/money/ @acme/billing @acme/payments-platform
/.github/ @acme/platform Ownership in monorepos is covered in path-based CODEOWNERS in a monorepo, and per-project CI in detecting affected projects from git diff.
Step 3 — Let release cadence vary by team Jump to heading
Teams that deploy continuously deploy their projects from main after each merge. Teams that release on a schedule cut per-product release branches from main. Both work against the same trunk.
# Web: deploy on merge when web is affected
on: { push: { branches: [main], paths: ["apps/web/**", "libs/ui-kit/**"] } }
# Billing: deploy on its own tags only
on: { push: { tags: ["billing-api@*"] } } Per-product release branches are described in release branches in a monorepo.
Step 4 — Protect shared code with stricter rules Jump to heading
Shared libraries are where one team’s change can break another’s product. Require approval from every consuming team’s owners for library changes, and run all dependents’ tests. Make breaking changes visible early, as in catching cross-package breaking changes.
# Who must approve a change to libs/money? Every owner listed for it.
gh api "repos/$OWNER/$REPO/contents/.github/CODEOWNERS" --jq .content | base64 -d | grep '^/libs/money/' Step 5 — Write the strategy down in one place Jump to heading
A monorepo strategy document covers the shared rules once and lets each team add a short section for its own cadence. New teams joining the repository read one page instead of discovering rules by breaking them.
# Branching in this repository
## Shared rules (all teams)
…
## Team sections
### Web — continuous deployment from main
### Billing — release/billing-api/X.Y every two weeks; fixes via labelled backports
### Data platform — continuous; export-api canaried before full rollout Step 6 — Revisit as teams and products change Jump to heading
A strategy chosen when the monorepo had three teams may not fit ten. Review it yearly, or whenever a new team joins, with the question: is any shared rule now blocking a team without protecting anyone?
Validation checklist Jump to heading
Frequently Asked Questions Jump to heading
Can one team keep using GitFlow in a monorepo? Jump to heading
Not with its own develop branch, which would be a second trunk. It can get the same effect with per-product release branches cut from main, which gives a stabilisation phase without a separate integration branch.
How do we handle a team that needs a different merge method? Jump to heading
Merge method is a repository setting, so it must be shared. Usually a team’s real need — preserved per-commit history, say — can be met another way, such as better squash messages or keeping detailed history in the pull request.
Who owns the shared rules? Jump to heading
A small platform or developer-experience group, with changes proposed by pull request and reviewed by representatives of each team.
Related Jump to heading
- Monorepo Branch Topology — the parent topic.
- Writing a Team Merge Policy — the shared merge rules in document form.
- Trunk-Based Development Setup — the trunk practices most monorepos adopt.
- Merge Queues & Required Checks — the shared landing mechanism.