Branching & Merging
Rust teams typically use trunk-based flow on main with short feat/* branches, optional release/* trains for multi-crate workspaces, and rebase to keep history reviewable.
Recipe
git checkout main
git pull --rebase origin main
git checkout -b feat/billing-tax
# work, commit
git fetch origin
git rebase origin/main
git push -u origin feat/billing-tax
# open PR -> squash merge to mainWhen to reach for this:
- Starting any ticket work
- Preparing PR for review
- Coordinating API + worker + migration releases
Working Example
# Release train for workspace 2.6.0
git checkout -b release/2.6.0 origin/main
# only bugfixes cherry-picked
git tag v2.6.0
git push origin v2.6.0
# Hotfix from production tag
git checkout -b hotfix/2.5.1 v2.5.0
git cherry-pick <fix-sha>
git push origin hotfix/2.5.1What this demonstrates:
- Feature branches branch from latest
main - Release branch stabilizes before tag
- Hotfix branches from production tag, not ahead-of-prod
main
Deep Dive
Merge Strategies
| Strategy | When |
|---|---|
| Squash merge | One commit per ticket on main |
| Rebase merge | Preserve commit granularity |
| Merge commit | Shared long-lived branches |
Rust-Specific Coordination
When sqlx migrations and binary deploys must align, cut release/* and run full cargo test --all-features before tag.
Gotchas
- Long-lived feature branches -
Cargo.lockconflicts multiply. Fix: rebase daily. - Merging
mainintorelease/*- pulls unvetted features. Fix: cherry-pick fixes only. - Rebase after PR approval - invalidates review SHA. Fix: rebase before final approval or merge queue.
- Force push
main- audit nightmare. Fix: branch protection blocks force push. - Binary + lib version skew - forgot to bump workspace crate. Fix: release checklist for all workspace members.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| GitFlow | Heavy release governance | Small continuous deploy team |
| Trunk only | Single binary service | Multi-artifact coordinated release |
| Merge queue | High concurrency monorepo | Tiny team |
FAQs
Rebase or merge for PR?
Team policy: squash to main is common; rebase locally before merge to keep CI green.
Multiple PRs same branch?
Avoid; one ticket per branch simplifies review and rollback.
Workspace crate branches?
Single branch can touch multiple crates; version bumps in one PR when coupled.
Related
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.