Skip to content

Repository Strategies

How you organize your source code repositories and enforce collaboration rules directly shapes how your CI/CD pipelines behave. A branching model that keeps code isolated for weeks cannot support Continuous Integration - by definition.


Branching strategies define when to create branches, how long they should live, and how they are merged back. The goal is always the same: keep the main branch deployable at all times while enabling parallel development.

Branching Strategies

Most workflows are built from a small set of standard branch archetypes:

Branch TypePurposeLifecycle
Main (main / master)The single source of truth. Must always be stable and deployable. Everything branches from it and merges back to it.Permanent
FeatureIsolates development of a specific feature or fix until it is complete, reviewed, and passes tests.Short-lived (hours to a few days)
ReleasePrepares a specific version for production. Only bug fixes allowed - never new features. Tagged with a version number on merge.Temporary (until the release ships)
HotfixAddresses critical production bugs with urgency. Branched from the live tag on main; merged back into both main and any active develop branch.Extremely short-lived
DevelopmentIntegration branch that collects multiple feature branches before they reach main. Common in legacy GitFlow.Long-lived (if used at all)

Branching Workflows

The three dominant branching workflows sit at different points on the integration spectrum - from most continuous to most structured:

Trunk-Based DevelopmentGitLab FlowGitFlow
Core ideaIntegrate directly to main multiple times per daymain as working branch, with environment-named branches (Production, Preprod)Separate develop branch + long-lived release/hotfix branches
Branch lifetimeHours (or direct to trunk)Short to mediumDays to weeks
Integration riskLow - small, frequent diffsMediumHigh - large merges with conflicts
CI/CD compatibilityContinuous DeploymentContinuous DeliveryContinuous Delivery
Best forSaaS, high-velocity teamsTeams needing environment promotion gatesVersioned products, regulated releases

Beyond the overall workflow, teams also layer specific delivery patterns on top. The choice should match the deployment model, not just developer preference:

PatternHow it worksBest paired with
Task branchingOne short-lived branch per task, merged immediately on completionTrunk-Based Development
Feature branchingBranch per feature, merged when the feature is fully readyMicroservices, GitLab Flow
Release (version) branchingDedicated branch per shipped version, used to isolate fixes for that versionGitFlow, packaged software

The repository model you choose determines how services relate to each other, how pipelines are triggered, and how teams coordinate.

Monorepo vs Polyrepo

MonorepoPolyrepo
What it isAll services and libraries live in one repositoryEach service has its own independent repository
Atomic changes✅ A single commit can span multiple services❌ Cross-service changes require coordinated PRs
Pipeline complexityHigh - pipelines must detect which sub-paths changedLow - each repo has a simple, focused pipeline
Dependency visibility✅ Internal dependencies are always in sync❌ Version mismatches between repos cause integration pain
Tooling requirementRequires Nx, Bazel, or Turborepo for change detection & cachingStandard tooling works out of the box
Used byGoogle, Meta, Uber, TwitterMost small-to-medium engineering teams

The right choice depends on organizational size and team structure. Teams with many independent microservices often start with polyrepo and migrate toward monorepo as cross-service coordination overhead grows.

Distributed microservices architectures have specific requirements. There are three common approaches, each with a different scope of isolation:

PatternStructureCI/CD implication
Full separationEvery microservice has its own dedicated repo and its own pipelinesMaximum independence; cross-service changes require coordinated releases
Separation by service typeRelated services (e.g., user management, payments) share one repoSimplifies shared database and config management; still keeps domains isolated
No separation (Monorepo)All microservice code lives in a single repoAtomic cross-service commits; requires change-detection tooling to avoid rebuilding everything on every push