Skip to content

Commit f6509b4

Browse files
authored
Merge pull request #1917 from contentstack/hotfix/DX-2957-branches-merge
fix: Merge failures occurring when using different strategies (overwrite with compare, merge base, merge compare)
2 parents f65288c + 409864c commit f6509b4

12 files changed

Lines changed: 679 additions & 44 deletions

File tree

.talismanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,5 @@ fileignoreconfig:
115115
- filename: pnpm-lock.yaml
116116
checksum: fc379207a835de8d851caa256837e2a50e0278c43e0251372f2a5292bee41fac
117117
- filename: package-lock.json
118-
checksum: da059d11bf1083833509cd963761d0d0916da7cf90943100735bf0ddc22e498f
118+
checksum: 0cb373716595912a75e9fd356e7a90a67eb1d2de712c454701231e2d5dd3caf7
119119
version: ""

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/contentstack-branches/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ $ npm install -g @contentstack/cli-cm-branches
3737
$ csdx COMMAND
3838
running command...
3939
$ csdx (--version)
40-
@contentstack/cli-cm-branches/1.4.2 darwin-arm64 node-v23.11.0
40+
@contentstack/cli-cm-branches/1.4.2 darwin-arm64 node-v22.14.0
4141
$ csdx --help [COMMAND]
4242
USAGE
4343
$ csdx COMMAND

packages/contentstack-branches/src/branch/merge-handler.ts

Lines changed: 94 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,13 @@ export default class MergeHandler {
108108
deleted: [],
109109
};
110110
const selectedItems = await selectCustomPreferences(module, this.branchCompareData[module]);
111-
if (!selectedItems.length) {
112-
cliux.print(chalk.red('No items were selected'));
113-
process.exit(1);
111+
if (selectedItems?.length) {
112+
forEach(selectedItems, (item) => {
113+
this.mergeSettings.mergeContent[module][item.status].push(item.value);
114+
this.mergeSettings.itemMergeStrategies.push(item.value);
115+
});
116+
this.mergeSettings.strategy = 'ignore';
114117
}
115-
forEach(selectedItems, (item) => {
116-
this.mergeSettings.mergeContent[module][item.status].push(item.value);
117-
this.mergeSettings.itemMergeStrategies.push(item.value);
118-
});
119-
this.mergeSettings.strategy = 'ignore';
120118
}
121119
} else if (this.strategy === 'merge_prefer_base') {
122120
if (this.strategySubOption === 'new') {
@@ -137,12 +135,25 @@ export default class MergeHandler {
137135
} else if (this.strategy === 'overwrite_with_compare') {
138136
this.mergeSettings.strategy = 'overwrite_with_compare';
139137
}
140-
if (this.checkEmptySelection()) {
141-
cliux.print(chalk.red('No items selected'));
142-
} else {
143-
await this.displayMergeSummary();
144-
}
145138

139+
const { allEmpty, moduleStatus } = this.checkEmptySelection();
140+
const strategyName = this.mergeSettings.strategy;
141+
142+
if (allEmpty) {
143+
cliux.print(chalk.red(`No items selected according to the '${strategyName}' strategy.`));
144+
process.exit(1);
145+
}
146+
147+
for (const [type, { exists, empty }] of Object.entries(moduleStatus)) {
148+
if (exists && empty) {
149+
const readable = type === 'contentType' ? 'Content Types' : 'Global fields';
150+
cliux.print('\n')
151+
cliux.print(chalk.yellow(`Note: No ${readable} selected according to the '${strategyName}' strategy.`));
152+
}
153+
}
154+
155+
this.displayMergeSummary();
156+
146157
if (!this.executeOption) {
147158
const executionResponse = await selectMergeExecution();
148159
if (executionResponse === 'previous') {
@@ -160,17 +171,71 @@ export default class MergeHandler {
160171
}
161172
}
162173

163-
checkEmptySelection() {
164-
for (let module in this.branchCompareData) {
165-
if (this.mergeSettings.mergeContent[module]?.modified?.length
166-
|| this.mergeSettings.mergeContent[module]?.added?.length
167-
|| this.mergeSettings.mergeContent[module]?.deleted?.length) {
168-
return false;
174+
/**
175+
* Checks whether the selection of modules in the compare branch data is empty.
176+
*
177+
* This method evaluates the branch compare data and determines if there are any changes
178+
* (added, modified, or deleted) in the modules based on the merge strategy defined in the
179+
* merge settings. It categorizes the status of each module as either existing and empty or
180+
* not empty.
181+
*
182+
* @returns An object containing:
183+
* - `allEmpty`: A boolean indicating whether all modules are either non-existent or empty.
184+
* - `moduleStatus`: A record mapping module types (`contentType` and `globalField`) to their
185+
* respective statuses, which include:
186+
* - `exists`: A boolean indicating whether the module exists in the branch comparison data.
187+
* - `empty`: A boolean indicating whether the module has no changes (added, modified, or deleted).
188+
*/
189+
checkEmptySelection(): {
190+
allEmpty: boolean;
191+
moduleStatus: Record<string, { exists: boolean; empty: boolean }>;
192+
} {
193+
const strategy = this.mergeSettings.strategy;
194+
195+
const useMergeContent = new Set(['custom_preferences', 'ignore']);
196+
const modifiedOnlyStrategies = new Set(['merge_modified_only_prefer_base', 'merge_modified_only_prefer_compare']);
197+
const addedOnlyStrategies = new Set(['merge_new_only']);
198+
199+
const moduleStatus: Record<string, { exists: boolean; empty: boolean }> = {
200+
contentType: { exists: false, empty: true },
201+
globalField: { exists: false, empty: true },
202+
};
203+
204+
for (const module in this.branchCompareData) {
205+
const content = useMergeContent.has(strategy)
206+
? this.mergeSettings.mergeContent[module]
207+
: this.branchCompareData[module];
208+
209+
if (!content) continue;
210+
211+
const isGlobalField = module === 'global_fields';
212+
const type = isGlobalField ? 'globalField' : 'contentType';
213+
moduleStatus[type].exists = true;
214+
215+
let hasChanges = false;
216+
if (modifiedOnlyStrategies.has(strategy)) {
217+
hasChanges = Array.isArray(content.modified) && content.modified.length > 0;
218+
} else if (addedOnlyStrategies.has(strategy)) {
219+
hasChanges = Array.isArray(content.added) && content.added.length > 0;
220+
} else {
221+
hasChanges =
222+
(Array.isArray(content.modified) && content.modified.length > 0) ||
223+
(Array.isArray(content.added) && content.added.length > 0) ||
224+
(Array.isArray(content.deleted) && content.deleted.length > 0);
225+
}
226+
227+
if (hasChanges) {
228+
moduleStatus[type].empty = false;
169229
}
170230
}
171-
return true;
231+
232+
const allEmpty = Object.values(moduleStatus).every(
233+
(status) => !status.exists || status.empty
234+
);
235+
236+
return { allEmpty, moduleStatus };
172237
}
173-
238+
174239
displayMergeSummary() {
175240
if (this.mergeSettings.strategy !== 'ignore') {
176241
for (let module in this.branchCompareData) {
@@ -269,10 +334,10 @@ export default class MergeHandler {
269334
};
270335

271336
const mergePreferencesMap = {
272-
'existing_new': 'merge_existing_new',
273-
'new': 'merge_new',
274-
'existing': 'merge_existing',
275-
'ask_preference': 'custom',
337+
existing_new: 'merge_existing_new',
338+
new: 'merge_new',
339+
existing: 'merge_existing',
340+
ask_preference: 'custom',
276341
};
277342
const selectedMergePreference = mergePreferencesMap[mergePreference];
278343

@@ -301,7 +366,10 @@ export default class MergeHandler {
301366

302367
if (scriptFolderPath !== undefined) {
303368
cliux.success(`\nSuccess! We have generated entry migration files in the folder ${scriptFolderPath}`);
304-
cliux.print('\nWARNING!!! Migration is not intended to be run more than once. Migrated(entries/assets) will be duplicated if run more than once', { color: 'yellow' });
369+
cliux.print(
370+
'\nWARNING!!! Migration is not intended to be run more than once. Migrated(entries/assets) will be duplicated if run more than once',
371+
{ color: 'yellow' },
372+
);
305373

306374
let migrationCommand: string;
307375
if (os.platform() === 'win32') {

packages/contentstack-branches/src/utils/branch-diff-utility.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,23 @@ async function branchCompareSDK(payload: BranchDiffPayload, skip?: number, limit
7979
const module = payload.module || 'all';
8080

8181
switch (module) {
82-
case 'content_types' || 'content_type':
82+
case 'content_types':
83+
case 'content_type':
8384
return await branchQuery
8485
.contentTypes(queryParams)
8586
.then((data) => data)
8687
.catch((err) => handleErrorMsg(err, payload.spinner));
87-
break;
88-
case 'global_fields' || 'global_field':
88+
case 'global_fields':
89+
case 'global_field':
8990
return await branchQuery
9091
.globalFields(queryParams)
9192
.then((data) => data)
9293
.catch((err) => handleErrorMsg(err, payload.spinner));
93-
break;
9494
case 'all':
9595
return await branchQuery
9696
.all(queryParams)
9797
.then((data) => data)
9898
.catch((err) => handleErrorMsg(err, payload.spinner));
99-
break;
10099
default:
101100
handleErrorMsg({ errorMessage: 'Invalid module!' }, payload.spinner);
102101
}

packages/contentstack-migration/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ $ npm install -g @contentstack/cli-migration
2121
$ csdx COMMAND
2222
running command...
2323
$ csdx (--version)
24-
@contentstack/cli-migration/1.7.0 darwin-arm64 node-v23.11.0
24+
@contentstack/cli-migration/1.7.2 darwin-arm64 node-v22.14.0
2525
$ csdx --help [COMMAND]
2626
USAGE
2727
$ csdx COMMAND

packages/contentstack-migration/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/cli-migration",
3-
"version": "1.7.1",
3+
"version": "1.7.2",
44
"author": "@contentstack",
55
"bugs": "https://github.com/contentstack/cli/issues",
66
"dependencies": {

packages/contentstack-migration/src/utils/modules.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ function executeShellCommand(pkg, directory = '') {
7272
try {
7373
const result = spawnSync(`npm`, ['i', pkg], { stdio: 'inherit', cwd: directory, shell: false });
7474
if (result?.error) throw result.error;
75-
console.log(`Command executed successfully: ${command}`);
75+
console.log(`Command executed successfully`);
7676
} catch (error) {
7777
console.error(`Command execution failed. Error: ${error?.message}`);
7878
}

packages/contentstack/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli
1818
$ csdx COMMAND
1919
running command...
2020
$ csdx (--version|-v)
21-
@contentstack/cli/1.40.0 darwin-arm64 node-v23.11.0
21+
@contentstack/cli/1.40.4 darwin-arm64 node-v22.14.0
2222
$ csdx --help [COMMAND]
2323
USAGE
2424
$ csdx COMMAND
@@ -3776,7 +3776,8 @@ USAGE
37763776
$ csdx launch:functions [-p <value>] [-d <value>]
37773777
37783778
FLAGS
3779-
-d, --data-dir=<value> [default: /Users/sunil.lakshman/Documents/cli/packages/contentstack] Current working directory
3779+
-d, --data-dir=<value> [default: /Users/aman.kumar/Documents/cli-repos/cli/packages/contentstack] Current working
3780+
directory
37803781
-p, --port=<value> [default: 3000] Port number
37813782
37823783
DESCRIPTION

packages/contentstack/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"@contentstack/cli-audit": "~1.12.1",
2626
"@contentstack/cli-auth": "~1.4.0",
2727
"@contentstack/cli-cm-bootstrap": "~1.14.0",
28-
"@contentstack/cli-cm-branches": "~1.4.1",
28+
"@contentstack/cli-cm-branches": "~1.4.2",
2929
"@contentstack/cli-cm-bulk-publish": "~1.8.0",
3030
"@contentstack/cli-cm-clone": "~1.14.0",
3131
"@contentstack/cli-cm-export": "~1.16.1",
@@ -37,7 +37,7 @@
3737
"@contentstack/cli-command": "~1.5.0",
3838
"@contentstack/cli-config": "~1.12.0",
3939
"@contentstack/cli-launch": "^1.8.0",
40-
"@contentstack/cli-migration": "~1.7.1",
40+
"@contentstack/cli-migration": "~1.7.2",
4141
"@contentstack/cli-utilities": "~1.11.0",
4242
"@contentstack/cli-variants": "~1.2.1",
4343
"@contentstack/management": "~1.20.3",

0 commit comments

Comments
 (0)