Version Control
Version Control in Salesforce development is the practice of tracking every metadata change to an org in a version control system (almost always Git) using Salesforce DX source format.
Definition
Version Control in Salesforce development is the practice of tracking every metadata change to an org in a version control system (almost always Git) using Salesforce DX source format. The codebase, the metadata, and the configuration all live in a Git repository alongside the project documentation, and every change (a new Apex class, a renamed field, a Flow update) goes through commits, branches, pull requests, and code review before it reaches a sandbox or production org.
The pattern is the standard modern alternative to the older click-driven, sandbox-to-sandbox-via-change-set workflow that dominated Salesforce development for the first decade of the platform. Version Control plus Salesforce DX plus a CI/CD pipeline together form the foundation of source-driven development, which is what every mature Salesforce team is moving toward in 2026. Some teams are already there; others are still climbing the curve.
Version Control on the Salesforce platform: format, branching, pipelines, and pain points
Why Salesforce needs version control more than most platforms
Salesforce stores almost everything as metadata: Apex code, Lightning components, custom objects, fields, flows, validation rules, profiles, layouts, permission sets. In a click-driven org-based workflow, all of this lives only inside the production org and the sandboxes that get refreshed from it. No history. No diff between yesterday and today. No way to know who changed what. Version Control fixes this by treating metadata the same way every other software discipline treats source code: every change is a commit, every commit has an author and a message, every change can be reverted, and the history is preserved for as long as the repository exists. The benefits compound over time; orgs that adopt Version Control early have fewer outages, faster releases, and better audit posture.
Salesforce DX source format and how metadata maps to files
Salesforce DX introduced a source format that maps Salesforce metadata to a file-and-folder structure suitable for version control. Each Apex class is a .cls file with a paired .cls-meta.xml file holding the API version and status. Custom objects break down into one file per field, one file per validation rule, one file per record type, all under a single object directory. Lightning Web Components live in their own folders with HTML, JavaScript, CSS, and an XML metadata file. Flows are XML files. Profiles are XML files with an explicit list of every field and object reference. The mapping is deterministic in both directions, so any developer can retrieve metadata from an org into source format and push source format back to an org through the Salesforce CLI.
Branching strategy: GitFlow, trunk-based, and what fits Salesforce
Branching strategy on Salesforce projects is the same conversation as any other software project, with one extra wrinkle: deployments to production orgs are slower and more expensive than deployments to typical web infrastructure. GitFlow with long-lived feature branches works for projects with infrequent releases. Trunk-based development with short-lived feature branches and frequent merges works for projects with daily or weekly releases. Most Salesforce teams land in the middle: trunk-based for the developer workflow, but with a Release Branch per scheduled production release to give QA a stable target. The right answer depends on release cadence, team size, and the maturity of the CI/CD pipeline. Pick one strategy, document it, and apply it consistently; mixing patterns creates merge conflicts that nobody wants to resolve.
Profiles, permission sets, and the metadata diff problem
Salesforce metadata has a notoriously hostile diff story for one specific reason: the Profile XML file. Each Profile contains a complete enumeration of every object the profile has access to, every field on every object, every Apex class the profile can run. Retrieving a Profile from a 5,000-field org produces a 50,000-line XML file. Adding one field flips lines all over the file. The diffs are unreadable, the merge conflicts are unsolvable, and the file size pushes the limits of every Git tool. The standard mitigation is two-fold: use Permission Sets and Permission Set Groups for everything you can (they have much smaller, much cleaner metadata), and use tools like Salesforce CLI source-tracking flags or third-party Sfpowerkit to clean Profile XML on retrieve. Profile XML is the single biggest source of pain in Salesforce version control.
CI/CD pipelines built on top of version control
Once metadata is in version control, the next layer is CI/CD: automated pipelines that run tests on every commit, deploy changes to sandboxes automatically, and promote releases to production through controlled gates. Standard tools include Jenkins, GitHub Actions, GitLab CI, CircleCI, and Salesforce-specific platforms like Copado, Gearset, AutoRABIT, and Flosum. Each tool reads from the Git repo, calls the Salesforce CLI to deploy metadata, runs Apex tests in the target org, and reports results. Mature pipelines also handle data deployments (test data, reference data) and validation runs (deploy without committing, to verify a change compiles in the target org before merging). The pipeline is where the version control story turns into measurable engineering velocity.
The org-based vs source-driven development split
In 2026, Salesforce teams broadly split into two camps. Org-based teams develop directly in sandboxes, use Change Sets or Workbench to deploy between orgs, and treat the production org as the source of truth. Source-driven teams develop in Scratch Orgs (or per-developer Developer Sandboxes), commit metadata to Git, and treat the Git repo as the source of truth. Salesforce explicitly recommends source-driven development as the strategic direction; org-based remains supported for smaller orgs or admin-heavy teams that have not yet justified the CI/CD investment. The shift requires upfront effort (set up Salesforce DX, train the team on Git, build the pipeline), but the long-term payoff in audit posture, release velocity, and change safety is substantial. Most projects that start in 2026 should default to source-driven.
Adopting Version Control on a Salesforce project
Adopting Version Control on a Salesforce project is a sequence of decisions that compound: pick a Git provider, set up a Salesforce DX project, decide on a branching strategy, retrieve existing metadata into source, build a baseline CI pipeline, and grow the pipeline over time. The full setup takes a few weeks of focused work, but each step delivers value on its own. Most teams that fail to adopt Version Control stall at the metadata retrieve step because the Profile XML diffs are too painful to manage; pre-plan for that.
- Set up the Git repository and the Salesforce DX project
Create a private Git repo on GitHub, GitLab, or Bitbucket. Initialize a Salesforce DX project with sfdx force:project:create or the modern sf project generate command. The project structure includes a manifest folder for package.xml files, a config folder for scratch org definitions, and a force-app folder for metadata. Commit the initial project structure. Add a .gitignore that excludes the .sfdx folder (local-only state) and any local environment files. Document the repository conventions in a CONTRIBUTING.md so future joiners know the structure.
- Retrieve existing metadata from the org into source
From the project root, authorize the source org (production or the most-current sandbox) with the Salesforce CLI. Run a metadata retrieve to pull every relevant metadata type into the force-app folder. This is where the Profile XML problem surfaces; expect very large, hard-to-diff files. Run a cleanup pass that removes Profile entries you do not control (managed package object references, for example) using Sfpowerkit or a custom script. Commit the cleaned baseline to a long-lived branch (typically main or master). This baseline is the starting point for all future work.
- Adopt a branching strategy and write it down
Pick GitFlow, trunk-based, or a hybrid based on your release cadence. Document the strategy in the repo CONTRIBUTING.md or in a separate ARCHITECTURE.md. Specify which branch maps to which environment (main maps to production, develop maps to integration sandbox, feature branches map to per-developer scratch orgs). Configure branch protection rules: main requires PR approval and passing CI checks before merge, develop allows direct push with passing checks. Train the team on the workflow with a hands-on session, not just a written doc.
- Build the initial CI pipeline
Set up a CI workflow that runs on every PR and every push to main. The workflow authorizes the relevant Salesforce org using a stored credential or JWT key, runs sf project deploy validate against the target sandbox, runs Apex tests with sf apex run test, and reports results back to the PR. Start with validation-only (deploy without committing) for PRs and full deploy for merges to main. Grow the pipeline over time to include data deployments, integration tests, and post-deploy verification. Document each pipeline stage and the credentials it needs in the repo README so future maintainers can update it.
- Profile XML diffs are notoriously unreadable. Use Permission Sets and Permission Set Groups for everything you can, and use tools like Sfpowerkit to clean Profile XML on retrieve.
- Salesforce DX source format and Metadata API format are different. Retrieving in the wrong format causes diff noise and merge conflicts. Stick to DX source format for the project.
- Scratch Orgs expire automatically (7 days default, 30 days max). Work that has not been pushed to source by expiration is lost. Push to Git as a daily habit, not at end-of-feature.
- CI deploys count against the daily API request limit on the target org. Run tests against scratch orgs or dedicated CI sandboxes; do not run them against production.
- Branch protection rules can be bypassed by anyone with admin rights to the repo. Use the bypass sparingly and audit it. Breaking the rule one time creates a culture problem.
Trust & references
Straight from the source - Salesforce's reference material on Version Control.
- Salesforce DX Developer GuideSalesforce Developer Docs
- Salesforce CLI ReferenceSalesforce Developer Docs
- Salesforce DevOps OverviewSalesforce Help
Hands-on resources to go deeper on Version Control.
About the Author
Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.
Test your knowledge
Q1. What is Version Control?
Q2. What tool is most common?
Q3. Why is it important?
Discussion
Loading discussion…