ADR 028: Git Branching Strategy¶
Status¶
Accepted
Context¶
A defined branching strategy ensures contributors know where to work, how
to propose changes, and what the release flow looks like. This complements
ADR 022 (rebase merge strategy) and
ADR 023 (branch protection), which cover
how code lands on main and what gates it must pass.
This ADR addresses a higher-level question: what branches exist, what are they for, and when are they created?
Forces¶
- This is a template repository — the branching model should be simple enough for solo developers yet scale to small teams
- CI workflows trigger on specific branch/event combinations (push to
main, PRs, tags) - release-please automates releases from
mainvia a Release PR - Branch protection rules require PR review and CI status checks on
main
Decision¶
Use a trunk-based development model with short-lived feature branches.
main is the single integration branch.
Branch categories¶
| Branch | Lifetime | Purpose | Convention |
|---|---|---|---|
main |
Permanent | Integration branch; always deployable | Protected, requires PR |
| Feature | Short-lived | New features, bug fixes, chores | feat/short-description, fix/short-description, chore/short-description |
| Release PR | Automated | Created by release-please | release-please--branches--main |
Rules¶
- All changes go through PRs into
main— no direct pushes (enforced by branch protection) - Feature branches are short-lived — ideally merged within a few days. Long-lived branches invite merge conflicts and integration pain.
- No
developbranch — trunk-based development usesmaindirectly. A separatedevelopbranch adds ceremony without benefit for this project's size. - No release branches — release-please handles releases from
mainvia tags. If a hotfix is needed for an older release, create a branch from the tag (rare, and documented in releasing.md). - Branch naming follows the conventional commit type — the prefix
(
feat/,fix/,docs/,chore/,ci/,refactor/,test/) matches the commit type, making the intent obvious in PR lists.
Workflow¶
- Create a branch from
main(feat/add-auth,fix/null-check) - Commit with conventional messages (ADR 009)
- Open a PR — CI gate (ADR 024) must pass
- Rebase and merge (ADR 022)
- Branch auto-deleted after merge
Alternatives Considered¶
Git Flow¶
Long-lived develop and main branches, with release/, hotfix/, and
feature/ branches.
Rejected because: Designed for projects with multiple supported releases
and scheduled release cycles. Overkill for a template that ships continuously
from main. Adds merge ceremony and branch management overhead with no
benefit at this scale.
GitHub Flow (with main only, no naming convention)¶
Simple model where all branches merge into main but without naming
conventions.
Rejected because: The model itself is essentially what we use, but adding a naming convention (type prefix) improves discoverability and aligns with the conventional commit strategy already in place.
Release branches¶
Maintain a release/x.y branch for each release series.
Rejected because: release-please handles releases via tags from main.
Creating release branches adds maintenance burden for a workflow that already
works without them.
Consequences¶
Positive¶
- Simple mental model —
mainplus short-lived branches - Aligns with existing ADRs (rebase merge, branch protection, conventional commits, CI gate)
- Branches are self-documenting via naming convention
- release-please integrates seamlessly with trunk-based development
- Auto-delete keeps the remote branch list clean
Negative¶
- No support for parallel release tracks out of the box (hotfixing v1 while developing v2 requires ad-hoc branching)
- Short-lived branch expectation doesn't prevent long-lived branches in practice — it's a convention, not a technical enforcement
Mitigations¶
- Stale branch cleanup can be automated (the template includes
cache-cleanup.ymlwhich handles cache expiry; branch staleness can be checked manually viaghCLI) - For the rare hotfix-on-old-version scenario, the process is documented in releasing.md
Implementation¶
- .github/workflows/ — Workflows trigger on
push: branches: [main]andpull_request: branches: [main] - ADR 022 — Merge strategy
- ADR 023 — Branch protection rules
- ADR 024 — CI gate pattern
- release-please-config.json — Release automation
References¶
- Trunk-based development
- GitHub Flow
- ADR 009 — Conventional commits
- ADR 021 — Automated release pipeline