Newer Version Available

This content describes an older version of this product. View Latest

Deploy and Retrieve Changes Identified by Source Tracking

When you create a Salesforce app, you typically use both low-code and pro-code techniques. An example of low-code is creating a custom object directly in an org using Setup. An example of pro-code is creating an Apex class in your local project using an IDE, such as VS Code. As you work, source tracking identifies changes so you can keep the remote metadata in the org in sync with the source in your local project.

The process is iterative. First you preview the remote and local changes. If conflicts exist, you resolve them. You must now ensure that these changes exist in both the org and your local project. So you retrieve the remote changes to your local project, then push them to your source control repository, to ensure that the source control system contains all your changes and is the source of historical truth. You deploy your local changes, such as Apex code, to the org so you can validate and test it. And you keep iterating through this process until you finish developing the Salesforce app.

To see source tracking in action, let’s look at some examples.

Say you run project retrieve preview and see remote changes.

1sf project retrieve preview --target-org DevSandbox
2
3No conflicts found.
4
5No files will be deleted.
6
7Will Retrieve [3] files.
8 Type         Fullname                          Path 
9 ──────────── ───────────────────────────────── ──── 
10 Layout       GizmoObject__c-GizmoObject Layout      
11 CustomObject GizmoObject__c                         
12 ApexClass    GizmoClass                             
13
14Ignored [2] files. These files won't retrieve because they're ignored by your .forceignore file.
15 Type    Fullname                            Path 
16 ─────── ─────────────────────────────────── ──── 
17 Profile Admin                                    
18 Profile B2B Reordering Portal Buyer Profile

Retrieve the changes in your org to your local project with the project retrieve start command. Now that the components have been created locally, the Path column has a value and it includes the default package directory.

1sf project retrieve start --target-org DevSandbox
2Preparing retrieve request... ⣟ Sending request to org
3Preparing retrieve request... Succeeded
4
5Retrieved Source
6=========================================================================================================================================
7| State   Name                              Type         Path                                                                             
8| ─────── ───────────────────────────────── ──────────��─ ──────────────────────────────────────────────────────────────────────────────── 
9| Created GizmoClass                        ApexClass    force-app/main/default/classes/GizmoClass.cls                                    
10| Created GizmoClass                        ApexClass    force-app/main/default/classes/GizmoClass.cls-meta.xml                           
11| Created GizmoObject__c                    CustomObject force-app/main/default/objects/GizmoObject__c/GizmoObject__c.object-meta.xml     
12| Created GizmoObject__c-GizmoObject Layout Layout       force-app/main/default/layouts/GizmoObject__c-GizmoObject Layout.layout-meta.xml

After retrieving the source, run project retrieve preview again. Now, source tracking reports that there’s nothing to retrieve.

1sf project retrieve preview 
2
3No conflicts found.
4
5No files will be deleted.
6
7No files will be retrieved.
8
9Ignored [2] files. These files won't retrieve because they're ignored by your .forceignore file.
10 Type    Fullname                            Path 
11 ─────── ─────────────────────────────────── ──── 
12 Profile Admin                                    
13 Profile B2B Reordering Portal Buyer Profile

Let’s now look at deploying. To preview your local changes, run project deploy preview.

1sf project deploy preview --target-org DevSandbox
2
3No conflicts found.
4
5No files will be deleted.
6
7Will Deploy [2] files.
8 Type         Fullname        Path                                                                           
9 ──────────── ─────────────── ────────────────────────────────────────────────────────────────────────────── 
10 ApexClass    WidgetClass     force-app/main/default/classes/WidgetClass.cls-meta.xml                        
11 CustomObject WidgetObject__c force-app/main/default/objects/WidgetObject__c/WidgetObject__c.object-meta.xml 
12
13No files were ignored. Update your .forceignore file if you want to ignore certain files.

Then deploy your local changes. After deploying to a sandbox, other developers that are using the sandbox can see your changes.

1sf project deploy start --target-org DevSandbox
2Deploying v59.0 metadata to test-ikspctiorkzs@example.com using the v59.0 SOAP API.
3Deploy ID: 0Af8D00000pNmKySAK
4Status: Succeeded | ████████████████████████████████████████ | 2/2 Components (Errors:0) | 0/0 Tests (Errors:0)
5
6Deployed Source
7=====================================================================================================================
8| State   Name            Type         Path                                                                           
9| ─────── ─────────────── ──────────── ────────────────────────────────────────────────────────────────────────────── 
10| Created WidgetClass     ApexClass    force-app/main/default/classes/WidgetClass.cls                                 
11| Created WidgetClass     ApexClass    force-app/main/default/classes/WidgetClass.cls-meta.xml                        
12| Created WidgetObject__c CustomObject force-app/main/default/objects/WidgetObject__c/WidgetObject__c.object-meta.xml

Run project deploy preview again.

1sf project deploy preview
2
3No conflicts found.
4
5No files will be deleted.
6
7No files will be deployed.
8
9No files were ignored. Update your .forceignore file if you want to ignore certain files.

The command reports there’s nothing to deploy, indicating that your local project and the org are synchronized.