An intelligent Git merge driver specifically designed for Salesforce metadata files. Eliminates hours of manual merge conflicts resolution.
- Saves time: No more manual XML conflict resolution
- Zero-config: Works immediately after installation
- Reliable: Understands Salesforce metadata structure
- Transparent: Seamless Git workflow integration
sequenceDiagram
participant Dev
participant Git
participant MergeDriver
Dev->>Git: git merge
Git->>MergeDriver: Detects XML conflict
MergeDriver->>MergeDriver: Analyzes metadata structure
MergeDriver->>MergeDriver: Smart merging
MergeDriver->>Git: Returns merged result
Git->>Dev: Clean commit (no conflicts)
This merge driver follows the zdiff3 conflict style philosophy:
- Shows the most compact diff possible: Only the specific conflicting elements are marked, not entire file sections
- Includes ancestor context: Conflicts display the base (ancestor) version alongside local and remote changes
- Respects Git configuration: Conflict marker size and labels are configurable via Git's standard parameters (
-L,-S,-X,-Yflags)
Example conflict output:
<<<<<<< ours
<field>localValue</field>
||||||| base
<field>originalValue</field>
=======
<field>remoteValue</field>
>>>>>>> theirsThis approach helps you understand:
- What the original value was (
base) - What your branch changed it to (
ours) - What the other branch changed it to (
theirs)
For metadata types where element order matters (like picklist values), the merge driver preserves ordering while intelligently merging changes:
- Disjoint reorderings merge automatically: If one branch reorders elements A↔B and another reorders C↔D, both changes are preserved
- Conflicting reorderings trigger conflict: If both branches move the same element to different positions, a conflict is raised for manual resolution
- Additions respect position: New elements are inserted at their intended position
Supported ordered metadata:
GlobalValueSet/StandardValueSet→ picklist valuesCustomField→ value set entriesRecordType→ picklist value assignments
This ensures picklist value ordering in your org matches what you expect after a merge.
# Install plugin (one time, global)
sf plugins install sf-git-merge-driver
# Configure merge driver in your project (one time, local per project)
cd my/sf/project
sf git merge driver installSFDX-Hardis VS Code extension has integrated the sf-git-merge-driver in its default dependencies, and offers a one click activation of the merge driver from the status bar, as shown below:
The merge driver activates automatically for conflicts on:
No additional steps required! Works during normal Git operations:
git pull # Conflicts resolved automatically
git merge # Same hereConfigured for these metadata files by default:
*.profile-meta.xml merge=salesforce-source
*.permissionset-meta.xml merge=salesforce-source
*.labels-meta.xml merge=salesforce-source
*.label-meta.xml merge=salesforce-source
*.applicationVisibility-meta.xml merge=salesforce-source
*.classAccess-meta.xml merge=salesforce-source
*.customMetadataTypeAccess-meta.xml merge=salesforce-source
*.customPermission-meta.xml merge=salesforce-source
*.customSettingAccess-meta.xml merge=salesforce-source
*.externalCredentialPrincipalAccess-meta.xml merge=salesforce-source
*.externalDataSourceAccess-meta.xml merge=salesforce-source
*.fieldPermission-meta.xml merge=salesforce-source
*.flowAccess-meta.xml merge=salesforce-source
*.objectPermission-meta.xml merge=salesforce-source
*.pageAccess-meta.xml merge=salesforce-source
*.recordTypeVisibility-meta.xml merge=salesforce-source
*.tabSetting-meta.xml merge=salesforce-source
*.userPermission-meta.xml merge=salesforce-source
*.objectSettings-meta.xml merge=salesforce-source
*.permissionsetgroup-meta.xml merge=salesforce-source
*.permissionSetLicenseDefinition-meta.xml merge=salesforce-source
*.mutingpermissionset-meta.xml merge=salesforce-source
*.sharingRules-meta.xml merge=salesforce-source
*.sharingCriteriaRule-meta.xml merge=salesforce-source
*.sharingGuestRule-meta.xml merge=salesforce-source
*.sharingOwnerRule-meta.xml merge=salesforce-source
*.sharingTerritoryRule-meta.xml merge=salesforce-source
*.workflow-meta.xml merge=salesforce-source
*.workflowAlert-meta.xml merge=salesforce-source
*.workflowFieldUpdate-meta.xml merge=salesforce-source
*.workflowFlowAction-meta.xml merge=salesforce-source
*.workflowKnowledgePublish-meta.xml merge=salesforce-source
*.workflowOutboundMessage-meta.xml merge=salesforce-source
*.workflowRule-meta.xml merge=salesforce-source
*.workflowSend-meta.xml merge=salesforce-source
*.workflowTask-meta.xml merge=salesforce-source
*.assignmentRules-meta.xml merge=salesforce-source
*.autoResponseRules-meta.xml merge=salesforce-source
*.escalationRules-meta.xml merge=salesforce-source
*.marketingappextension-meta.xml merge=salesforce-source
*.matchingRule-meta.xml merge=salesforce-source
*.globalValueSet-meta.xml merge=salesforce-source
*.standardValueSet-meta.xml merge=salesforce-source
*.globalValueSetTranslation-meta.xml merge=salesforce-source
*.standardValueSetTranslation-meta.xml merge=salesforce-source
*.translation-meta.xml merge=salesforce-source
*.objectTranslation-meta.xml merge=salesforce-sourceWhen you don't want to use the merge driver for a specific merge, just backup the .git/info/attributes file and put it back after the merge.
mv .git/info/attributes .git/info/attributes.bak
git merge <branch>
mv .git/info/attributes.bak .git/info/attributesIf you want to disable the merge driver for a specific file, just comment the merge driver configuration from the .git/info/attributes file.
# *.profile-meta.xml merge=salesforce-sourceIf you want to disable it for all the project, just uninstall the driver:
sf git merge driver uninstallYou can check if the merge driver is installed by running the following command:
git config --show-origin --get-regexp '^merge.salesforce-source(\..*)?'You can check if the merge driver is enabled by running the following command:
grep "merge=salesforce-source" .git/info/attributesThe plugin will add content in the file $GIT_DIR/info/attributes to enable the merge driver.
This files need to be present for the plugin to be installed.
Ensure the repository is properly cloned / checked out in CI/CD context before installing the plugin.
If the merge driver encounters a list of elements (like fields in a profile, or permissions in a permission set) but does not know which field acts as the "key" (unique identifier) for that type, it will fallback to standard conflict behavior. This means you might see a conflict block containing the entire array instead of a smart merge of individual elements.
If you encounter this behavior for a Salesforce metadata type the driver is supposed to handle, please open an issue! We can add the missing key definition to support smart merging for that type.
If you encounter this behavior for a Salesforce metadata type the driver does not already handle, please open an issue! We can evaluate how to support smart merging for that type.
The plugin uses the Salesforce CLI logging system to log information.
You can control the logging level by setting the SF_LOG_LEVEL environment variable.
You can redirect the logging in the terminal using DEBUG=sf-git-merge-driver.
You can also use GIT_TRACE=1 to get more information about git operations.
You can also use GIT_MERGE_VERBOSITY=5 to get more information about the merge process.
Git environment variables are detailed here.
Example:
DEBUG=sf-git-merge-driver
SF_LOG_LEVEL=trace # can be error | warn | info | debug | trace, default: warn
GIT_MERGE_VERBOSITY=5 # can be 0 to 5
GIT_TRACE=true
git merge ...sf git merge driver disablesf git merge driver enablesf git merge driver installsf git merge driver runsf git merge driver uninstall
Uninstalls the local git merge driver for the given org and branch.
USAGE
$ sf git merge driver disable [--json] [--flags-dir <value>]
GLOBAL FLAGS
--flags-dir=<value> Import flag values from a directory.
--json Format output as json.
DESCRIPTION
Uninstalls the local git merge driver for the given org and branch.
Uninstalls the local git merge driver for the given org and branch, by removing the merge driver content in the
`.git/info/attributes` files in the project, deleting the merge driver configuration from the `.git/config` of the
project, and removing the installed binary from the node_modules/.bin directory.
ALIASES
$ sf git merge driver disable
EXAMPLES
Uninstall the driver for a given project:
$ sf git merge driver disable
Installs a local git merge driver for the given org and branch.
USAGE
$ sf git merge driver enable [--json] [--flags-dir <value>]
GLOBAL FLAGS
--flags-dir=<value> Import flag values from a directory.
--json Format output as json.
DESCRIPTION
Installs a local git merge driver for the given org and branch.
Installs a local git merge driver for the given org and branch, by updating the `.git/info/attributes` files in the
project, creating a new merge driver configuration in the `.git/config` of the project, and installing the binary in
the node_modules/.bin directory.
ALIASES
$ sf git merge driver enable
EXAMPLES
Install the driver for a given project:
$ sf git merge driver enable
Installs a local git merge driver for the given org and branch.
USAGE
$ sf git merge driver install [--json] [--flags-dir <value>]
GLOBAL FLAGS
--flags-dir=<value> Import flag values from a directory.
--json Format output as json.
DESCRIPTION
Installs a local git merge driver for the given org and branch.
Installs a local git merge driver for the given org and branch, by updating the `.git/info/attributes` files in the
project, creating a new merge driver configuration in the `.git/config` of the project, and installing the binary in
the node_modules/.bin directory.
ALIASES
$ sf git merge driver enable
EXAMPLES
Install the driver for a given project:
$ sf git merge driver install
See code: src/commands/git/merge/driver/install.ts
Runs the merge driver for the specified files.
USAGE
$ sf git merge driver run -O <value> -A <value> -B <value> -P <value> [--json] [--flags-dir <value>] [-L <value>] [-S
<value>] [-X <value>] [-Y <value>]
FLAGS
-A, --local-file=<value> (required) path to our version of the file
-B, --other-file=<value> (required) path to their version of the file
-L, --conflict-marker-size=<value> [default: 7] number of characters to show for conflict markers
-O, --ancestor-file=<value> (required) path to the common ancestor version of the file
-P, --output-file=<value> (required) path to the file where the merged content will be written
-S, --ancestor-conflict-tag=<value> [default: base] string used to tag ancestor version in conflicts
-X, --local-conflict-tag=<value> [default: ours] string used to tag local version in conflicts
-Y, --other-conflict-tag=<value> [default: theirs] string used to tag other version in conflicts
GLOBAL FLAGS
--flags-dir=<value> Import flag values from a directory.
--json Format output as json.
DESCRIPTION
Runs the merge driver for the specified files.
Runs the merge driver for the specified files, handling the merge conflict resolution using Salesforce-specific merge
strategies. This command is typically called automatically by Git when a merge conflict is detected.
EXAMPLES
Run the merge driver for conflicting files:
$ sf git merge driver run --ancestor-file=<value> --local-file=<value> --other-file=<value> \
--output-file=<value>
Where:
- ancestor-file is the path to the common ancestor version of the file
- local-file is the path to our version of the file
- other-file is the path to their version of the file
- output-file is the path to the file where the merged content will be written
See code: src/commands/git/merge/driver/run.ts
Uninstalls the local git merge driver for the given org and branch.
USAGE
$ sf git merge driver uninstall [--json] [--flags-dir <value>]
GLOBAL FLAGS
--flags-dir=<value> Import flag values from a directory.
--json Format output as json.
DESCRIPTION
Uninstalls the local git merge driver for the given org and branch.
Uninstalls the local git merge driver for the given org and branch, by removing the merge driver content in the
`.git/info/attributes` files in the project, deleting the merge driver configuration from the `.git/config` of the
project, and removing the installed binary from the node_modules/.bin directory.
ALIASES
$ sf git merge driver disable
EXAMPLES
Uninstall the driver for a given project:
$ sf git merge driver uninstall
See code: src/commands/git/merge/driver/uninstall.ts
changelog.md is available for consultation.
Versioning follows SemVer specification.
Contributions are what make the trailblazer community such an amazing place. We regard this component as a way to inspire and learn from others. Any contributions you make are appreciated.
See contributing.md for sgd contribution principles.
This project license is MIT - see the LICENSE.md file for details


