I'm using DX for my Continuous Integration, but post-scratch org when I want to deploy into a traditional sandbox for staging, I'm struggling with an automated way to deploy only the new commits (as opposed to ALL of the metadata) in my Dev Branch. Is anyone using a script that archives this (dynamically creates the package.xml based on the most recent commit)?

The use case is that without this, I am deploying ALL the metadata each time, hitting the limit of 10,000 files.

2 Answers 2


I use the legacy/community maintained ForceCLI project to do delta deployments when not using Salesforce DX. It's pretty easy to get a basic workflow going using a shell script.

You can do something like this:

git diff [...] --name-only --diff-filter=ACM | force push -f -

What this does is get a list of changed files between two Git revisions (you'd replace [...] with either a reference to a start and end commit, or an expression like HEAD~1 for a delta of HEAD against the previous commit) and list their paths. It then pipes those paths into force, which will automatically construct a package.xml and run the delta deployment.

I've found a few issues with ForceCLI around delta-deploying unpacked Static Resources and Lightning Components (I believe the latter has already been fixed, but may not have been released yet), but those issues are more or less easily worked around with a little Bash. For static resources, I use a script that zips them up and then pipes the git diff output through sed to squash all references to static resource elements to a reference to the zip file, e.g.

sed -E 's#^src/staticresources/([^/]+)/.+#src/staticresources/\1\.resource#

Note that one thing this approach doesn't handle is deletions. I delete metadata so rarely that I have not invested the effort to script delta deletions. Since deletions can be run either pre- or post-deploy and sometimes need to be one or the other, I've felt the effort to introspect the desired delete operation off of a commit message was more than it was worth.

  • In my case, I'm already installing the Salesforce CLI on the server... do you know if I could use sfdx force:mdapi:deploy in lieu of the force push command with the legacy CLI? Commented Dec 17, 2018 at 14:56
  • As far as I know, you'd have to generate the delta package.xml yourself to use sfdx force:mdapi:deploy. I don't believe it has functionality to do that, although I'd be delighted to be wrong.
    – David Reed
    Commented Dec 17, 2018 at 14:57
  • I'll give it a whirl. The one thing I hate about this is that I really liked the JWT auth flow that the sfdx CLI has. Based on what I've seen, I'll have to do the old fashioned password+token for this flow. Aside from that, it should work fine and I technically don't need the new CLI for anything else. Commented Dec 17, 2018 at 19:20
  • While I have not used it, ForceCLI claims to support JWT -- see force help login: force login --connected-app-client-id <my-consumer-key> -u username -key jwt.key
    – David Reed
    Commented Dec 17, 2018 at 19:38

There is now sfdx-git-delta which allows you provide which commits you'd like to generate a deployment for. It can identify the changed metadata since a reference commit & build the destructiveChanges.xml from the deleted (or renamed) metadata


sfdx plugins:install sfdx-git-delta

Git output of diff between latest commit (HEAD) and the previous commit (HEAD^)

sfdx sgd:source:delta --to "HEAD" --from "HEAD^" --output "."

The above generates 2 useful artifacts

  1. A package.xml file inside a package folder. This package.xml will contain the added/changed metadata to deploy
  2. A destructiveChange.xml file, inside a destructiveChanges folder. This contains the removed/renamed metadata to delete from the target org.

As opposed to the above generated files, you can have it generate a source folder by using --generate delta in the delta command. This is useful for objects where you just want to deploy what specifically changed vs. the entire sub-folder.

Deploy the delta metadata

sfdx force:source:deploy -x package/package.xml --postdestructivechanges destructiveChanges/destructiveChanges.xml

Or split the deploy operations up

echo "--- package.xml generated with added and modified metadata ---"
cat package/package.xml
echo "---- Deploying added and modified metadata ----"
sfdx force:source:deploy -x package/package.xml

echo "--- destructiveChanges.xml generated with deleted metadata ---"
cat destructiveChanges/destructiveChanges.xml
echo "--- Deleting removed metadata ---"
sfdx force:mdapi:deploy -d destructiveChanges --ignorewarnings

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .