Git branching for Salesforce is more constrained than branching for a web application. You can’t spin up a new Salesforce org the way you spin up a Docker container. Sandboxes are expensive, slow to refresh, and limited in number. Your branching strategy has to account for that.
Here’s the model that works for large teams running multiple concurrent projects.
The Problem With Gitflow in Salesforce
Gitflow - with its feature branches, develop branch, release branches, and hotfix branches - is a reasonable model for many projects. For Salesforce at scale, it breaks down because:
- Merges are expensive - metadata merges often require conflict resolution that only a Salesforce developer can do, not just a diff algorithm
- Sandbox scarcity - you can’t run a branch per feature the way you’d run a container per PR
- Release trains - Salesforce teams often release on a fixed cadence, with features that miss the train holding for the next one
The Model: Trunk-Based with Release Trains
A model that works well for large Salesforce teams running multiple concurrent projects:
main (production)
↑
release/2024-Q4 (release candidate - locked at release day minus 2)
↑
develop (integration branch - always deployable to Full Sandbox)
↑↑↑
feature/PROJ-123 feature/PROJ-456 feature/PROJ-789
Main reflects production exactly. It’s the source of truth for what’s live. Tagged on every deployment.
Release branches are cut from develop at “code freeze” (typically two business days before the release date). Only bug fixes merge into a release branch - no new features. This is what gets deployed to production.
Develop is always deployable. Every feature merged to develop must pass all CI checks and be deployable to the Full Sandbox. If develop is broken, that’s a P1.
Feature branches are short-lived - 1-3 days maximum. Longer-lived feature work is broken into smaller deployable increments. This is the most important discipline to enforce.
Managing Concurrent Projects
With five concurrent projects, the main challenge is avoiding “big bang” merges where two projects have been developing independently and their metadata conflicts in ways no automated tool can resolve.
The solution is cross-project integration testing. Every feature branch, before merge to develop, runs against a snapshot of all other in-progress features. This is expensive but far cheaper than a merge crisis at release time.
In Copado, this means running your pipeline against a Multi-Cloud integration org, not just the project’s own sandbox.
Hotfixes
Hotfixes bypass the release train:
main ← hotfix/PROJ-999 → develop
The hotfix branches from main (not develop), is deployed directly to production via an expedited pipeline, and is immediately back-merged to develop. Any in-progress release branches also get the fix merged.
The rule: a hotfix is only for production-breaking issues. “The client wants this today” is not a hotfix. Enforce this - once the expedited pipeline exists, everyone wants to use it.
Copado Configuration
In Copado, map your branches to your environments explicitly:
| Branch | Environment | Deployment trigger |
|---|---|---|
feature/* | Developer sandbox | Manual |
develop | Full Sandbox | Automatic on merge |
release/* | Staging (UAT) | Automatic on commit |
main | Production | Manual approval required |
The key Copado setting: Back Promotion Policy. When a hotfix or release fix merges to main, Copado should automatically back-promote the change to develop. Without this, you’ll have production diverge from your development branch within weeks.
What Doesn’t Work
- One sandbox per developer - costs too much, creates integration debt
- Merging features directly to main - even with review, this skips integration testing
- No code freeze - teams that keep merging features until the day of release have release day incidents consistently
- Long-lived feature branches - every day a branch lives, the merge cost grows
The discipline that matters most: short-lived feature branches, fast feedback, mandatory integration branch. Everything else is tuning.