Branches Foundations
Comparing Branches
Introduction
In Contentstack, the Branch Compare feature allows users to analyze the differences between two branches: the Base branch (typically 'main') and the Compare branch (where desired changes are made). This comparison serves to understand changes before merging them into the base branch.
Methods of Comparison
When comparing branches, users can view differences in:
- Content types and global fields
- Specific content types
- Specific global fields
Comparison Status:
Three outcomes are possible:
1. Base only: base only notifies that a particular content type or global field is present only in the base branch and is not present in the compare branch.
2. Compare only: compare only notifies that a particular content type or global field is present only in the compare branch and is not present in the base branch.
3. Modified: The item exists in both branches but has been altered.
Use Cases:
1. Modifying a Content Type:
- Scenario: Altering fields without impacting the source branch.
- Approach: Create a child branch inheriting from the main branch, make changes, and then compare.
- Status: Differences are marked as "modified."
We are going to modify the fields present in the Author content type.
Let's first see the structure of the Author content type in the source branch i.e., in the main branch.

We will change field names First Name to Author First Name and Last Name to Author Last Name in the compare branch i.e., dev branch.
Also, we are going to change the field from SEO Global field
Let's first see the structure of the SEO Global field in the source branch i.e., in the main branch

We changed the Meta Title filed to the SEO Meta Title in the dev branch.

2. Adding a New Feature:
- Scenario: Introducing a new content type.
- Approach: Create a new branch, make changes, and then compare with the main branch.
- Status: Differences are marked as "compare only" if the new content type is only in the compare branch.
We are going to add a new content type named "Branch Demo" in the dev branch


Now let's do the comparison by using Content Management API as well as CLI
First will see all compare operations with API
1)
curl --location 'https://api.contentstack.io/v3/stacks/branches_compare?compare_branch=dev'
\ --header 'api_key: *****************'
\ --header 'authorization: ******************'
\ --header 'Content-Type: application/json'
\ --data ''
Result
{
"branches": {
"base_branch": "main",
"compare_branch": "dev"
},
"diff": [
{
"title": "SEO",
"uid": "seo",
"type": "global_field",
"status": "modified"
},
{
"title": "Branch Demo",
"uid": "branch_demo",
"type": "content_type",
"status": "compare_only"
},
{
"title": "Author",
"uid": "author",
"type": "content_type",
"status": "modified"
}
]
}

2) Compare Content Type between Branches
curl --location 'https://api.contentstack.io/v3/stacks/branches_compare/content_types?compare_branch=dev' \
--header 'api_key: ******************' \
--header 'authorization: ******************' \
--header 'Content-Type: application/json' \
--data ''
Result
{
"branches": {
"base_branch": "main",
"compare_branch": "dev"
},
"diff": [
{
"title": "Branch Demo",
"uid": "branch_demo",
"type": "content_type",
"status": "compare_only"
},
{
"title": "Author",
"uid": "author",
"type": "content_type",
"status": "modified"
}
]
}

3) Compare Global Fields between Branches
curl --location 'https://api.contentstack.io/v3/stacks/branches_compare/global_fields?compare_branch=dev' \
--header 'api_key: *****************' \
--header 'authorization: ********************' \
--header 'Content-Type: application/json' \
--data ''
Result
{
"branches": {
"base_branch": "main",
"compare_branch": "dev"
},
"diff": [
{
"title": "SEO",
"uid": "seo",
"type": "global_field",
"status": "modified"
}
]
}

4) Compare Specific Content Types between Branches
curl --location 'https://api.contentstack.io/v3/stacks/branches_compare/content_types/author?compare_branch=dev' \
--header 'api_key: ******************' \
--header 'authorization: *******************' \
--header 'Content-Type: application/json' \
--data ''
Result
{
"branches": {
"base_branch": "main",
"compare_branch": "dev"
},
"diff": {
"uid": "author",
"type": "content_type",
"status": "modified",
"base_branch": {
"differences": [
{
"display_name": "First Name",
"uid": "title",
"data_type": "text",
"mandatory": true,
"unique": true,
"field_metadata": {
"_default": true,
"version": 3
},
"multiple": false,
"non_localizable": false,
"indexed": false,
"inbuilt_model": false,
"path": "schema[0]"
},
{
"data_type": "text",
"display_name": "Last Name",
"uid": "last_name",
"field_metadata": {
"description": "",
"default_value": "",
"version": 3
},
"format": "",
"error_messages": {
"format": ""
},
"mandatory": false,
"multiple": false,
"non_localizable": false,
"unique": false,
"indexed": false,
"inbuilt_model": false,
"path": "schema[1]"
}
],
"schema": null
},
"compare_branch": {
"differences": [
{
"display_name": "Author First Name",
"uid": "title",
"data_type": "text",
"mandatory": true,
"unique": true,
"field_metadata": {
"_default": true,
"version": 3
},
"multiple": false,
"non_localizable": false,
"indexed": false,
"inbuilt_model": false,
"path": "schema[0]"
},
{
"data_type": "text",
"display_name": "Author Last Name",
"uid": "last_name_dev",
"field_metadata": {
"description": "",
"default_value": "",
"version": 3
},
"format": "",
"error_messages": {
"format": ""
},
"mandatory": false,
"multiple": false,
"non_localizable": false,
"unique": false,
"indexed": false,
"inbuilt_model": false,
"path": "schema[1]"
}
],
"schema": null
}
}
}

5) Compare Specific Global Fields between Branches
curl --location 'https://api.contentstack.io/v3/stacks/branches_compare/global_fields/seo?compare_branch=dev' \
--header 'api_key: *****************' \
--header 'authorization: *********************' \
--header 'Content-Type: application/json' \
--data ''
Result
{
"branches": {
"base_branch": "main",
"compare_branch": "dev"
},
"diff": {
"uid": "seo",
"type": "global_field",
"status": "modified",
"base_branch": {
"differences": [
{
"data_type": "text",
"display_name": "Meta Title",
"uid": "meta_title",
"field_metadata": {
"description": "",
"default_value": "",
"version": 3
},
"format": "",
"error_messages": {
"format": ""
},
"multiple": false,
"mandatory": false,
"unique": false,
"non_localizable": false,
"indexed": false,
"inbuilt_model": false,
"path": "schema[0]"
}
],
"schema": null
},
"compare_branch": {
"differences": [
{
"data_type": "text",
"display_name": "SEO Meta Title",
"uid": "meta_title",
"field_metadata": {
"description": "",
"default_value": "",
"version": 3
},
"format": "",
"error_messages": {
"format": ""
},
"multiple": false,
"mandatory": false,
"unique": false,
"non_localizable": false,
"indexed": false,
"inbuilt_model": false,
"path": "schema[0]"
}
],
"schema": null
}
}
}

Now let's see all compare operations using the Command Line Interface (CLI)
The comparison results are distinguished based on the following:
A “+” symbol with green highlighted text: Indicates that this is present only in the compare branch.
A “±” symbol with blue highlighted text Indicates that this is present in both branches but has different values.
A “-” symbol with red highlighted text: Indicates that this is not present in the compare branch.
csdx cm:branches:diff --help
Differences between two branches
USAGE
$ csdx cm:branches:diff [--base-branch ] [--compare-branch ] [-k ][--module ]
FLAGS
-k, --stack-api-key= Provide Stack API key to show difference between branches
--base-branch= Base branch
--compare-branch= Compare branch
--format= [default: compact-text] [Optional] Type of flags to show branches differences
--module= Module
DESCRIPTION
Differences between two branches
EXAMPLES
$ csdx cm:branches:diff
$ csdx cm:branches:diff --stack-api-key "bltxxxxxxxx"
$ csdx cm:branches:diff --compare-branch "dev"
$ csdx cm:branches:diff --compare-branch "dev" --stack-api-key "bltxxxxxxxx"
$ csdx cm:branches:diff --compare-branch "dev" --module "content-types"
$ csdx cm:branches:diff --module "content-types" --format "detailed-text"
$ csdx cm:branches:diff --compare-branch "dev" --format "detailed-text"
$ csdx cm:branches:diff --stack-api-key "bltxxxxxxxx" --base-branch "main"
$ csdx cm:branches:diff --stack-api-key "bltxxxxxxxx" --base-branch "main" --compare-branch "dev"
$ csdx cm:branches:diff --stack-api-key "bltxxxxxxxx" --base-branch "main" --module "content-types"
$ csdx cm:branches:diff --stack-api-key "bltxxxxxxxx" --base-branch "main" --compare-branch "dev" --module "content-types"
$ csdx cm:branches:diff --stack-api-key "bltxxxxxxxx" --base-branch "main" --compare-branch "dev" --module "content-types" --format "detailed-text"
1) Get all module's difference

2) Get all content types difference

3) Get all global fields' difference

Conclusion:
Comparing branches in Contentstack facilitates safe development and integration of changes, allowing users to manage modifications effectively before merging them into the main branch.