env:flowmerge

Merges metadata from one Environment into another.

Process

  1. Flow In the source and target environments (optional- see --noSourceIn and --noTargetIn options).
  2. Merge the metadata from the source environment into the target environment.
  3. Flow Out the target environment to deploy the result of the merge in to the target environment's Salesforce organization (optional- see the --noTargetOut option).

Options

  • --stack=<stackName>

    The name of the stack to target. Stack names are case-insensitive. Stacks are specific to license keys, and you can see a list of all available stacks with the stack:list command.

    This value is required if no valid default stack has been set, or if you would like to target a stack other than the one that is currently the default stack. You can use the stack:setdefault command to set or change the default stack.

  • -f|--from=<environmentName>

    Required. Prompted for when not specified, and possible to do so.

    The name of the environment to merge from. Environment names are case-insensitive.

  • -i|--into=<environmentName>

    Required. Prompted for when not specified, and possible to do so.

    The name of the environment to merge into. Environment names are case-insensitive.

    The metadata changes from the environment specified to the --from option will be merged into the metadata in the --into environment.

  • -k|--encryptionKey=<key>

    The key used to encrypt or decrypt stored credentials.

    Required if:

    • You want the process to utilise previously encrypted credentials, or if you want the process to save credentials
    • AND the encryption key has not been saved locally with the auth:key:save command, or the key that has been saved locally is not the key that you wish to use
  • --noSourceIn

    If specified, the inbound flow of metadata from the --from environment is not performed. Instead, only the metadata changes that are already in that environment's Git branch will be merged into the --into environment.

  • --sourceInRetrieveMode=auto|partial|full

    Specifies how metadata is retrieved from the source Salesforce org. The default value is auto.

    • auto: Favor a Partial Retrieve if it is safe and possible to do so, fall back to a full retrieve if not
    • partial: Never fall back to a full retrieve, always do a partial retrieve (even if it is not safe to do so); fail if it is not possible to do a partial retrieve (e.g. if source tracking is not enabled in the org)
    • full: Always do a full retrieve, even if a partial retrieve would be possible
  • --sourceInConflicts=prompt|allAsLocal|allAsRemote|askForEach|gitMergetool|abort

    Specifies how unresolved merge conflicts encountered during the inbound flow of the source environment should be handled. The default value is prompt.

    • prompt: Prompt user interactively for each encountered set of unresolved merge conflicts if possible, otherwise abort the inbound flow
    • allAsLocal: Resolve all merge conflicts by letting the version in the Git branch win
    • allAsRemote: Resolve all merge conflicts by letting the incoming version from the Salesforce org win
    • askForEach: Let user choose between local and remote for each conflicted file
    • gitMergetool: Run configured git-mergetool command for each encountered set of unresolved merge conflicts
    • abort: Abort the inbound flow if any unresolved merge conflicts are encountered
  • --noTargetIn

    If specified, the inbound flow of metadata from the --into environment is not performed. Instead, the metadata changes from the --into environment will be merged with the changes in the --from environment's Git branch.

    warning icon
    warning

    --noTargetIn can increase the risk of clobber to the org. This is because any metadata changes in the --into environment's Salesforce organization that are not already in the --into environment's Git branch will be overwritten by the deployment to the --into environment. The --clobber arg allows control of how to handle clobber if it is encountered.

  • --targetInRetrieveMode=auto|partial|full

    Specifies how metadata is retrieved from the taget Salesforce org. The default value is auto.

    • auto: Favor a Partial Retrieve if it is safe and possible to do so, fall back to a full retrieve if not
    • partial: Never fall back to a full retrieve, always do a partial retrieve (even if it is not safe to do so); fail if it is not possible to do a partial retrieve (e.g. if source tracking is not enabled in the org)
    • full: Always do a full retrieve, even if a partial retrieve would be possible
  • --targetInConflicts=prompt|allAsLocal|allAsRemote|askForEach|gitMergetool|abort

    Specifies how unresolved merge conflicts encountered during the inbound flow of the target environment should be handled. The default value is prompt.

    • prompt: Prompt user interactively for each encountered set of unresolved merge conflicts if possible, otherwise abort the inbound flow
    • allAsLocal: Resolve all merge conflicts by letting the version in the Git branch win
    • allAsRemote: Resolve all merge conflicts by letting the incoming version from the Salesforce org win
    • askForEach: Let user choose between local and remote for each conflicted file
    • gitMergetool: Run configured git-mergetool command for each encountered set of unresolved merge conflicts
    • abort: Abort the inbound flow if any unresolved merge conflicts are encountered
  • --conflicts=prompt|allAsLocal|allAsRemote|askForEach|gitMergetool|abort

    Specifies how unresolved merge conflicts should be handled during the merge from the source branch into the target branch. The default value is prompt.

    • prompt: Prompt user interactively for each encountered set of unresolved merge conflicts if possible, otherwise abort the inbound flow
    • allAsLocal: Resolve all merge conflicts by letting the version in the Git branch win
    • allAsRemote: Resolve all merge conflicts by letting the incoming version from the Salesforce org win
    • askForEach: Let user choose between local and remote for each conflicted file
    • gitMergetool: Run configured git-mergetool command for each encountered set of unresolved merge conflicts
    • abort: Abort the inbound flow if any unresolved merge conflicts are encountered
  • --diffMode=auto|history|org

    Specifies the diffing algorithm to use when comparing metadata in the Git branch to the metadata in the Salesforce org during the outound flow of the target environment. The default value is auto.

    • auto: Use history diff if supported, otherwise fall back to full diff
    • history: Use History diff if supported, otherwise abort
    • org: Use @concept_orgdiff
  • --noTargetOut

    If specified, the merged metadata is not deployed to the --into environment's Salesforce organization.

    The specified conflict resolution strategy applies only to files which could not automatically resolved by Git. If not specified, the default behavior is equal to prompt.

  • --clobber=auto|accept|abort

    Specifies how Clobber should be handled, if encountered during the outbound flow of the target environment. Default is auto.

    • auto: Allow potential clobber, but abort on certain clobber
    • accept: Allow all clobber (both potential and certain)
    • abort: Do not allow any clobber (either potential or certain), and abort before any changes are deployed to the target Salesforce org.
  • -g|--gitOnly

    Shorthand for --noSourceIn --noTargetIn --noTargetOut (i.e. only the Git based operations will be performed, and there will be no interaction with Salesforce).

  • -c|--checkOnly

    If specified, the merge result will be validated, but it won't be persisted.

    This means that:

    • The result of the merge will not be pushed to your remote Git repository
    • The deployment to the --into environment's Salesforce organization (if any) will be validated by Salesforce, but the changes will not be deployed.
warning icon
warning

Using this option can potentially leave a validated changeset with in the target Salesforce organisation and the Salesforce UI will show a button to 'Quick Deploy' a validated changeset.

Using the 'Quick Deploy' option will cause the metadata tracked with OrgFlow to be out of sync, which may cause further OrgFlow operations to incorrectly merge or overwrite metadata changes.

  • --allOrNothing

    Either deploy all detected changes to the target org successfully, or nothing at all. If specified, this option instructs OrgFlow to finalize deployment to the target org only if no failures occur on the first attempt.

    An outbound flow is normally performed in a successive exclude-and-retry loop, where any components that failed to deploy in one attempt are excluded in the next attempt, until the deployment succeeds (which may then effectively be a partial deployment).

    Specifying this option changes this logic in order to avoid committing a partial deployment to the target org. With this option set, the first attempt is performed as a normal deployment, and if it succeeds without failures, then the changes are committed to the target org and the outbound flow is considered successful. However, if the first deployment attempt fails, then subsequent attempts are changed to validation-only deployments — still performed in order to collect a complete set of errors — and no changes are committed to the target org and the outbound flow is considered unsuccessful, regardless of the outcome of those validation-only deployment attempts. In the case of a merge flow, the merge result is not pushed to the remote repository.

  • --testLevel=[NoTestRun|RunSpecifiedTests|RunLocalTests|RunAllTestsInOrg]

    If specified, indicates the tests that should be executed as part of the deployment to Salesforce:

    • NoTestRun: No tests are executed.
    • RunSpecifiedTests: Only the test classes specified by --tests are executed.
    • RunLocalTests: All tests in the organization that do not originate from managed packages are executed.
    • RunAllTestsInOrg: Every test in the organization (including those in managed packages) are executed.

    All deployments are subject to Salesforce's minimum test requirements (e.g. code coverage etc.), regardless of the value that you specify for this option.

    If omitted, Salesforce will automatically determine the tests to execute:

    • If deploying to a sandbox, then no tests are run.
    • If deploying to a production organization and the deployment contains changes to Apex classes or triggers, then RunLocalTests.
  • --tests=<testClassNames>

    Only valid (and required) if --testLevel=RunSpecifiedTests.

    A comma separated list of test class names to execute. Example: --test=MyControllerTests,MyTriggerTests

  • --jUnitTo=<filePath>

    If specified, the OrgFlow CLI will output the results of the test run to a JUnit format file. This file can be read by many CI/CD tools to report on the results of the test run.

  • --keepDelta=<directoryPath>

    If specified, the OrgFlow CLI will retain the delta deployment archives that are uploaded to Salesforce as part of the deployment process. The delta archives will be placed into the directory specified. This can be useful in scenarios where you need to troubleshoot deployment problems.

  • --waitForLock=<minutes>

    The maximum amount of time to wait (in minutes) for environments currently locked by other users or OrgFlow instances to be released. Default is 0 (i.e. do not wait but rather fail this command immediately).

    Any command that mutates the state of an environment in any way always acquires an exclusive lock on that environment, to prevent other instances from trying to mutate the same environment simultaneously - something that could have unpredictable results. Particularly in scripted or CI/CD scenarios, it can be useful to have OrgFlow wait a certain amount of time for an already locked environment to become available, rather than failing immediately and requiring the script to be executed again.


The following options are global across all commands:

  • -h|--help

    If specified, prints help for this command instead of executing it.

  • -l|--licenseKey=<key>

    The License Key you were issued to allow you to use the OrgFlow CLI. If a valid key is supplied, it is stored locally on the machine so that it does not need to be specified again on the next execution.

  • --acceptEula

    If specified, you are signifying that you accept our End User License Agreement (EULA). You only need to specify this once per device, because your acceptance will be cached on the device (you can pass --acceptEula=false if you wish to clear this). You must accept our EULA to be able to run most OrgFlow commands.

  • --logTo=<filePath>

    If specified, a log file is written to the specified path. The specified path may contain one or more tokens; see Logging for more information.

  • --logLevel=[Verbose|Debug|Information|Warning|Error|Fatal]

    Default: Information

    The minimum log level to be written to the log file; logs below this level will not be written. Only effective if a valid value for --logTo has been specified.

  • --diagnostic=[Auto|Always|Never]

    Default: Auto

    If the CLI encounters an exception then it will ask (where possible) the user whether or not to create a Diagnostic Bundle and write it to disk. If it is not able to prompt then no action is taken. This is the default behaviour (Auto).

    You can change this default behaviour (and suppress the prompt) by specifying either Always or Never (which will always write the bundle or never write the bundle, respectively). This is particularly useful in a CI/CD context, where the CLI may not be able to prompt, but you still want to create diagnostic bundles for all failures.

  • --diagnosticDirPath=<directoryPath>

    If specified, sets the location to write the Diagnostic Bundle (if any). If not specified, a default location will automatically be chosen. This default location depends on a number of factors, including the operating system and some file-system based restrictions that might be in place. The location that the diagnostic bundle is ultimately written to is always included in the standard error output of the CLI.

  • --noConfirm

    If specified, suppresses confirmation prompts that the CLI might raise before performing destructive or dangerous procedures. If suppressed, the CLI assumes that the prompts would have been answered positively and continues with execution.

  • --progress=[Interactive|Never|Always]

    Default: Interactive

    Controls how progress is printed to the standard error stream:

    • Interactive: Progress is sent to the standard error stream only if the standard error stream is connected to an interactive terminal.
    • Never: Progress is not sent to the standard error stream.
    • Always: Progress is sent to the standard error stream, even if that stream has been redirected.
  • --tempDir=<directoryPath>

    If specified, sets the location to use as storage for files that may need to be stored on disk temporarily during command execution. For example, the location on disk where zip files containing metadata from Salesforce are downloaded to before they are unzipped.

    If not specified, the CLI will automatically choose an appropriate location on disk (usually in the current user's temporary storage location). This automatically chosen location may be deeply nested within a drive, which may be problematic if the operating system imposes limits on file path lengths and the files placed into temporary storage have particularly long paths or names.

  • --json

    Switches the format of the output sent to the standard output stream to JSON. This is the most verbose output available, and is useful for scripting or automation.

  • --forceSignIn.

    If specified, the CLI will ignore any cached Salesforce access tokens, and will require the Salesforce authentication process to be re-completed for each organisation that the command connects to.

  • --maxTransientErrorRetries=<count>.

    If no value is specified, the CLI will indefinitely retry any process that fails due to a transient error. This is the default behaviour, and allows for resilience against temporary issues that might otherwise cause a process to fail.

    Specify a positive integer value to prevent indefinite retries. Each process that fails due to a transient error will be retried up to a maximum amount of times specified. For example, --maxTransientErrorRetries=5: Each process that fails will be re-tried up to a maximum of five times. If an earlier process fails four times but then succeeds on the fifth attempt, the counter is reset for the next process.

    Specify --maxTransientErrorRetries=0 to disable transient failure retries.

  • --maxTransientErrorDelay=<seconds>.

    Default: 60

    Processes retried due to a transient error are delayed by a back-off policy that gradually increases the time to wait between retries. Specify a non-negative integer value as the maximum amount of seconds to wait between attempts.

    Specify --maxTransientErrorDelay=0 to disable the back-off policy and always instantly retry failed processes.

Examples

Interactively merge an environment into another:

orgflow env:flowmerge

Commit (flow in) the changes from the test and production environments, merge the changes from test into the production environment, and deploy the result of the merge into the production Salesforce organization:

orgflow env:flowmerge --from=test --into=production

Commit (flow in) the changes from the test and production Salesforce organizations, merge the changes from test into the production environment, and deploy the result of the merge into the production Salesforce organization:

orgflow env:flowmerge --from=test --into=production

Merge the changes from environments dev1, dev2, and dev3 into production. The changes from the production Salesforce environment are retrieved only once (at the start), and the result of all three merges are deployed together (at the end):

orgflow env:flowmerge --from=dev1 --into=production --noTargetOut

orgflow env:flowmerge --from=dev2 --into=production --noTargetIn --noTargetOut

orgflow env:flowmerge --from=dev3 --into=production --noTargetIn