Managing Deployment Environments within Version Control Repositories


Bicycle

As software development scales, robust handling of deployment environments — development, staging, and production — becomes essential. Each environment has unique needs for configuration, access control, and stability. A foundational decision every team faces is how to model these environments within version control.

As your deployment landscape matures, the management of multiple environments—such as development, staging, and production—becomes critical to a smooth workflow, stability, and velocity. A major architectural decision is how you represent these environments in version control.

This article explores three dominant strategies:

  • Branching Model: Multiple environment branches in a single repository.
  • Forked Repository Model: Each environment is isolated as a forked repo.
  • Trunk-Based Development (TBD): Everyone works on a single main branch; environments are managed via deployment and configuration.

Option 1: Using Multiple Branches

How it Works

  • Environments are represented as branches (develop, staging, main) within a single repository.
  • Feature development happens on feature branches, merged into environment branches via pull/merge requests (PRs/MRs).
  • Deployments per environment are triggered by changes to that environment’s branch.

Pros

  • Centralized History: All changes live under one repo, making tracking and code review straightforward.
  • Smooth Promotions: Merging from develop to staging to main aligns with normal PR/MR workflows.
  • Easy Diffing: You can see what’s in staging vs. production with simple branch comparisons.

Cons

  • Merge Conflicts: Diverging hotfixes/config can cause tricky merges between environment branches.
  • Config Leaks: Risk of unintentionally carrying environment-specific settings across branches.
  • Branch Divergence: Long-lived or poorly synchronized branches are difficult to reconcile.

Option 2: Using Forked Repositories Per Environment

How it Works

  • Each environment gets its own repository, implemented as a fork of the authoritative (usually production) repo:
    • myapp-dev (fork of myapp-staging)
    • myapp-staging (fork of myapp-prod)
    • myapp-prod (the authority or main fork)
  • Development happens primarily in the dev (or upstream) fork.
  • Synchronization occurs via pull or merge requests between forks: e.g., PR from myapp-dev to myapp-staging, then from myapp-staging to myapp-prod.

Example Workflow

  1. Code is developed in myapp-dev.
  2. When ready, a PR is created from myapp-dev to myapp-staging.
  3. After staging validation, a PR is made from myapp-staging to myapp-prod.

Pros

  • Total Isolation: Each environment can have its settings, permissions, even diverge in code for environment-specific tweaks.
  • Explicit Promotions: Promotions between environments become high-visibility, formalized PRs across forks, making reviews and checkpoints explicit.
  • Enforced Access Control: Repo-level permissions restrict who can change what and where.

Cons

  • Increased Overhead: Developers and automation must remember to keep forks in sync, and it’s harder to share code quickly between environments.
  • Synchronization Complexity: Manual or scripted PRs between forks can become cumbersome, with the potential for omission or delay.
  • Duplication of Tooling/CI: Each repository needs its pipeline configuration, secrets, integrations, and maintenance, but can be managed in a dedicated (external) repository

Option 3: Trunk-Based Development (TBD)

In Trunk-Based Development, everyone commits directly to a single branch—often called main or trunk. Deployment environments are handled dynamically, using configuration, feature flags, and deployment automation, rather than multiple branches or forks.

How it works

  • Very short-lived (if any) feature branches.
  • Continuous integration: commit/merge to main, test/auto-deploy.
  • Feature flags toggle unfinished/new work.
  • Environments reflect deploys from a common source, differentiated by deploy-time config.

Pros

  • Simplest History: No merge conflict headaches.
  • Fast Feedback: Continuous integration and deployment possible.
  • Low Overhead: No branch/fork sync; all changes always ready to deploy.
  • Promotes DevOps: Encourages development and operations to collaborate closely.

Cons

  • Requires Discipline and Automation: Must invest in feature flags, robust testing, and solid CI/CD.
  • Limited Isolation: Environments differ mainly by config; not full code isolation as in forks.
  • Immediate Exposure: Risk of broken code reaching shared mainline—requires strong review, CI, and test culture.

Choosing the Right Model - Which Suits Your Team?

Comparison Table

FeatureBranching ModelForked Repo ModelTrunk-Based Development
Single Central Codebase❌ (multiple forks)
Strict Environment Isolation🟠 Partial❌ (config only)
Merge/Pull Overhead🟠 Moderate❌ High✅ Minimal
CI/CD Complexity🟠❌ High✅ Streamlined
Code Promotion✅ Merge PRs✅ Cross-repo PRs✅ Tag/Config Deploy
Feature Flag Use Required❌ Optional❌ Optional✅ Essential
Modern DevOps Alignment🟠 Somewhat❌ Uncommon✅ Yes

In summary

  • Branching model is familiar and effective for most small-to-midsize teams.
  • Forks provide maximal isolation at the cost of sync pain—consider when stringent environment fencing is business-critical.
  • Trunk-Based Development is the lean, modern path: one branch, feature flags, solid CI/CD, and continuous delivery—ideal for teams investing in DevOps, automation, and rapid iteration.

Choosing your model depends on your priorities: safety, speed, or separation. In the next articles, we’ll show how to implement automation for each approach.

Coming Up Next

In this series our follow-up articles, we’ll show:

  • How to set up automated CI/CD for each model
  • How to handle PR/merge mechanics for code promotion
  • How to organize secrets/config per environment
Go Back explore our courses

We are here for you

You are interested in our courses or you simply have a question that needs answering? You can contact us at anytime! We will do our best to answer all your questions.

Contact us