Skip to main content

Git branching and pull requests

This repository uses a lightweight Git Flow: long-lived main and develop branches, short-lived topic branches, and pull requests for all substantive changes.

Review gate: PRs from branches into develop

All normal work lands on develop only through a pull request from a topic branch (feat/*, docs/*, etc.). That PR is where code review, discussion, and approval happen—there is no separate approval step; merging the PR is accepting the change into the integration branch.

  • Open every topic branch as a PR targeting develop (never main for day-to-day features or docs).
  • Required reviews before merge (configure branch protection on develop in GitHub to enforce this). GitHub Actions does not run on PRs to develop by default (see ADR 0008) to save CI minutes—run the same checks locally (root README.md scripts) before merge, or trigger Actions → Docs → Run workflow manually if you need a green run.
  • Do not push commits directly to develop; use a PR so the diff and history stay reviewable (same idea as main).

Hotfixes are the exception: they still use PRs, but the first PR may target main; see Hotfixes and backport to develop.

Branches

BranchRole
mainProduction-ready history. Only receives merges from release preparation or hotfixes. Protected: no direct pushes; CI must pass. Tags (e.g. v1.2.0) mark releases.
developReview and merge target for all topic branches: integration branch where approved PRs land. This is the default base for feature and documentation PRs. Keep it green locally (typecheck + builds); automated CI on develop PRs is currently off by policy.
Topic branchesShort-lived. Created from develop (or from main only for urgent hotfixes). Work is proposed via PR → develop for review, then the branch is deleted after merge.

Branch naming

Use lowercase, slashes for hierarchy, and a type prefix so automation and humans can scan history quickly.

PrefixUse
feat/New user-visible behavior or capability
fix/Bug fixes
docs/Documentation, ADRs, comments only
chore/Tooling, CI, dependencies without feature change
refactor/Internal restructuring without behavior change
test/Tests only
release/Preparing a release (version bumps, changelog) — rare; often a PR from developmain suffices
hotfix/Urgent fix branched from main, merged back to main and develop

Examples: feat/invoices-export, docs/adr-observability, fix/login-redirect, chore/bun-upgrade.

Day-to-day flow (most changes)

  1. Sync develop: git checkout develop && git pull origin develop.
  2. Create a branch: git checkout -b docs/short-topic (or feat/..., etc.).
  3. Commit often with Conventional Commits (feat:, fix:, docs:, …).
  4. Push and open a pull request from your branch into develop. This PR is the review and approval step—request reviewers, respond to feedback, iterate until approved.
  5. Merge only after approval (per team rules) and local verification (or a manually triggered workflow run) so you are not bypassing quality—PRs to develop do not get automatic GitHub Actions. Use Squash and merge (preferred) or Merge commit if preserving branch history is explicitly needed. Avoid rebase-merge on shared branches unless the team agrees.
  6. Delete the remote branch after merge (GitHub can do this automatically).

Releases: developmain

When develop is ready for production:

  1. Open a pull request from develop into main (title e.g. Release YYYY-MM-DD or chore: release vX.Y.Z).
  2. Use merge commit or squash per team preference for release PRs; many teams use a merge commit on main to preserve the integration point, or squash for a single release commit—pick one convention and stay consistent.
  3. Tag main after merge (vX.Y.Z).
  4. Deploy or trigger release automation from main / tags as defined for your environment.

Hotfixes

  1. Branch from main: hotfix/critical-issue.
  2. Fix, PR into main, merge, tag patch release.
  3. Backport the same fix into develop (merge main into develop or cherry-pick) so the fix is not lost on the next release.

Pull request expectations

  • Small, reviewable diffs — split large work when possible.
  • Describe what changed and why; link issues or ADRs when relevant.
  • Quality before merge — for PRs to develop, run local checks (or workflow_dispatch in GitHub) because automated CI on those PRs is off; for PRs to main, the Docs workflow must be green. No secret or credential commits.
  • Squash and merge from feature branches into develop keeps history readable (one logical commit per PR).

Conventional commits (summary)

<type>[optional scope]: <description>

[optional body]

Types: feat, fix, docs, style, refactor, perf, test, chore, ci, build.

This matches ADR 0005 and improves changelogs and bisect.

Quick reference

git checkout develop && git pull origin develop
git checkout -b feat/my-change
# ... work, commit ...
git push -u origin feat/my-change
# Open PR → develop, merge (squash), delete branch