2.1.4.1. Branching Models: Trunk-Based, GitHub Flow, and GitFlow
2.1.4.1. Branching Models: Trunk-Based, GitHub Flow, and GitFlow
Branching strategy determines how code flows from developer to production. Trunk-based development — where developers commit small changes directly to main, often behind feature flags — minimizes merge conflicts and enables continuous integration. GitHub Flow adds lightweight feature branches merged through pull requests, suitable for teams that value code review before integration. GitFlow uses long-lived develop and release branches, appropriate for packaged software with multiple supported versions but often too heavyweight for SaaS. The key insight: shorter-lived branches mean fewer conflicts. Every day a branch stays open, the main branch diverges further. Azure Repos branch policies enforce quality server-side — minimum reviewers, build validation, comment resolution, and work item linking — physically preventing merges that don't meet standards.
| Trunk-based | GitHub Flow | GitFlow | |
|---|---|---|---|
| Long-lived branches | main only | main only | main + develop |
| Branch lifetime | Hours to a day | Days | Days to weeks |
| Release branches | No | No | Yes |
| Hides unfinished work with | Feature flags | Feature flags | The branch itself |
| Best fit | Continuous delivery of one hosted version | Continuous delivery with review gates | Several released versions supported at once |
| Main cost | Requires disciplined flag hygiene | Little, at small scale | Merge overhead and divergence |
Branch naming conventions improve automation and readability. Prefixes like feature/, bugfix/, hotfix/, and release/ enable path-based pipeline triggers and communicate intent. Azure Repos supports hierarchical branch organization: feature/auth/oauth-refresh nests under feature/auth/, making large repositories navigable.
Pull request workflows enforce quality through automation. Required reviewers can be set per path — changes to /infrastructure/ require platform team review, while /api/ changes require backend team review. Auto-complete eliminates merge ceremony: the developer sets it when creating the PR, and merge happens automatically once all policies pass. PR templates standardize what reviewers need to assess — a checklist of "tests added," "docs updated," "breaking changes documented."
For monorepos, GitHub's CODEOWNERS file assigns reviewers automatically based on changed paths. Azure Repos has no CODEOWNERS support — the equivalent is the Automatically included reviewers branch policy, which takes a path filter and can be marked required.
Merge strategies affect history and conflict resolution. Merge commits preserve branching history (useful for understanding when features were integrated). Squash merges compress a feature branch into a single commit (cleaner history, harder to debug individual changes). Rebase and fast-forward create linear history (cleanest, but rewrites commits).
Azure Repos enforces merge strategy per branch through branch policies: require squash merges for feature branches into main, allow merge commits for release branches. This creates a clean mainline while preserving detailed development history on feature branches when needed for post-merge debugging.
Fork-based workflows separate contributor permissions from maintainer permissions. External contributors fork the repository, push to their fork, and submit cross-repository pull requests. The maintainer reviews the PR without granting the contributor write access to the main repository. This is the standard model for open-source collaboration and can also serve internal teams with strict access controls between organizational units.
Pull request workflows are the enforcement mechanism for branching policies. Azure Repos auto-complete eliminates merge ceremony — developers set auto-complete when creating the PR, and merge happens automatically the moment all policies pass without requiring a manual "Complete" click. Squash merging condenses feature branch commits into a single commit on main, simplifying history at the cost of losing individual commit detail. Semi-linear merge (rebase + merge commit) preserves individual commits while maintaining a clean graph structure.
The choice between merge strategies — merge commit, squash, and rebase — affects traceability and history readability differently for each team workflow.