From 3ab2db4967a823f2323da5ae5081a86d26ac3f6d Mon Sep 17 00:00:00 2001 From: David First Date: Fri, 30 Aug 2024 13:48:46 -0400 Subject: [PATCH] feat(merge-lane)!: change no-snap to avoid fast-forward (#9159) Until now, in case lane-b is merged into lane-a and a component (e.g. comp-a) is ahead in lane-b, we simply updated lane-a with the new snap of lane-b. (this behavior is similar to the "fast-forward" in Git). This was true regardless of `--no-snap` flag. The `--no-snap` flag was only for cases when comp-a is diverged in history and no conflicts found, which was auto-snapping the component and saving two parents, the head of lane-a and the head of lane-b. In come cases, the end result of such a merge is not desirable. Some changes might be done to this comp-a in lane-b which I would like to investigate and test before I decide to get them in lane-a. Although comp-a wasn't changed/snapped in my lane-a, still, I prefer to get the changes of comp-a as modified, so then `bit diff` will show the new changes I'm getting and then I can decide later to snap these changes. This PR makes this possible by using the `--no-snap` flag. In practice, it considers this state of target-ahead (lane-b) as diverged, which, as a result - doesn't update lane-a, only the component-files and the unmerged files with the heads data. A new flag `--no-auto-snap` was introduced to keep the previous behavior of `--no-snap` in case users need them. --- e2e/harmony/lanes/bit-remove-on-lanes.e2e.ts | 4 +- e2e/harmony/lanes/merge-lanes.e2e.ts | 77 ++++++++++++++++--- e2e/harmony/merge-config.e2e.ts | 31 ++++---- e2e/harmony/updates-from-main-and-lane.e2e.ts | 2 +- .../merging/merge-status-provider.ts | 11 ++- .../component/merging/merging.main.runtime.ts | 12 +-- scopes/lanes/merge-lanes/merge-lane.cmd.ts | 18 ++++- .../merge-lanes/merge-lanes.main.runtime.ts | 4 + 8 files changed, 122 insertions(+), 37 deletions(-) diff --git a/e2e/harmony/lanes/bit-remove-on-lanes.e2e.ts b/e2e/harmony/lanes/bit-remove-on-lanes.e2e.ts index 8d0bbfba8da..930736293db 100644 --- a/e2e/harmony/lanes/bit-remove-on-lanes.e2e.ts +++ b/e2e/harmony/lanes/bit-remove-on-lanes.e2e.ts @@ -324,10 +324,10 @@ describe('bit lane command', function () { expect(staged).to.include(`${helper.scopes.remote}/comp2`); }); }); - describe('when merging with --no-snap', () => { + describe('when merging with --no-auto-snap', () => { before(() => { helper.scopeHelper.getClonedLocalScope(beforeMerge); - output = helper.command.mergeLane('lane-a', '-x --no-snap'); + output = helper.command.mergeLane('lane-a', '-x --no-auto-snap'); }); it('bit status should not show the component as soft-removed from remote', () => { const status = helper.command.statusJson(); diff --git a/e2e/harmony/lanes/merge-lanes.e2e.ts b/e2e/harmony/lanes/merge-lanes.e2e.ts index 8d8fb7c5fca..044115d7ee2 100644 --- a/e2e/harmony/lanes/merge-lanes.e2e.ts +++ b/e2e/harmony/lanes/merge-lanes.e2e.ts @@ -523,7 +523,7 @@ describe('merge lanes', function () { describe('merge the lane without snapping', () => { before(() => { helper.scopeHelper.getClonedLocalScope(beforeMerge); - helper.command.mergeLane('main', '--auto-merge-resolve theirs --no-snap -x'); + helper.command.mergeLane('main', '--auto-merge-resolve theirs --no-auto-snap -x'); }); it('should show the during-merge as modified', () => { const status = helper.command.statusJson(); @@ -664,12 +664,12 @@ describe('merge lanes', function () { expect(() => helper.command.export()).to.not.throw(); }); }); - describe('bit lane merge with --resolve-unrelated and --no-snap', () => { + describe('bit lane merge with --resolve-unrelated and --no-auto-snap', () => { before(() => { helper.scopeHelper.getClonedRemoteScope(remoteScopeAfterExport); helper.scopeHelper.getClonedLocalScope(afterLaneExport); helper.command.import(); - helper.command.mergeLane('main', '--resolve-unrelated --no-snap'); + helper.command.mergeLane('main', '--resolve-unrelated --no-auto-snap'); }); it('bit status should show the component as during-merge and staged and not everywhere else', () => { helper.command.expectStatusToBeClean(['componentsDuringMergeState', 'stagedComponents']); @@ -701,7 +701,7 @@ describe('merge lanes', function () { helper.scopeHelper.getClonedRemoteScope(remoteScopeAfterExport); helper.scopeHelper.getClonedLocalScope(afterLaneExport); helper.command.import(); - helper.command.mergeLane('main', '--resolve-unrelated theirs --no-snap'); + helper.command.mergeLane('main', '--resolve-unrelated theirs --no-auto-snap'); }); it('bit status should show the component as during-merge and staged and not everywhere else', () => { helper.command.expectStatusToBeClean(['componentsDuringMergeState', 'stagedComponents']); @@ -1063,7 +1063,7 @@ describe('merge lanes', function () { }); describe('when the lane is merged to main, so currently on the FS the file exits', () => { before(() => { - helper.command.mergeLane('dev', '--no-squash --no-snap -x'); + helper.command.mergeLane('dev', '--no-squash --no-auto-snap -x'); }); // previously the file was removed it('should not remove the file', () => { @@ -1074,7 +1074,7 @@ describe('merge lanes', function () { before(() => { helper.scopeHelper.getClonedLocalScope(beforeMerge); helper.command.switchLocalLane('dev', '-x'); - helper.command.mergeLane('main', '--no-snap -x'); + helper.command.mergeLane('main', '--no-auto-snap -x'); }); // previously it was in "remain-deleted" state and the file was not created it('should add the file', () => { @@ -1329,7 +1329,7 @@ describe('merge lanes', function () { helper.command.snapAllComponentsWithoutBuild(); helper.command.export(); helper.command.switchLocalLane('main', '-x'); - mergeOutput = helper.command.mergeLane('lane-a', '-x --no-snap'); + mergeOutput = helper.command.mergeLane('lane-a', '-x --no-auto-snap'); }); it('should indicate that this file was removed in the output', () => { expect(mergeOutput).to.have.string('removed foo.js'); @@ -1353,7 +1353,7 @@ describe('merge lanes', function () { helper.command.switchLocalLane('main', '-x'); helper.command.tagAllWithoutBuild('--unmodified'); helper.command.export(); - mergeOutput = helper.command.mergeLane('lane-a', '-x --no-snap --no-squash'); + mergeOutput = helper.command.mergeLane('lane-a', '-x --no-auto-snap --no-squash'); }); it('should indicate that this file was removed in the output', () => { expect(mergeOutput).to.have.string('removed foo.js'); @@ -1409,7 +1409,7 @@ describe('merge lanes', function () { }); // previously it was throwing the "unrelated" error it('bit-lane-merge should not throw', () => { - expect(() => helper.command.mergeLane('main', '-x --no-snap')).to.not.throw(); + expect(() => helper.command.mergeLane('main', '-x --no-auto-snap')).to.not.throw(); }); }); describe('renaming files from uppercase to lowercase', () => { @@ -1629,4 +1629,63 @@ describe('merge lanes', function () { expect(comp1.head).to.equal(oldSnapComp1); }); }); + describe('--no-snap vs --no-auto-snap', () => { + let beforeMerge: string; + let snapLaneA: string; + let snapLaneB: string; + before(() => { + helper.scopeHelper.setNewLocalAndRemoteScopes(); + helper.command.createLane('lane-a'); + helper.fixtures.populateComponents(1); + helper.command.snapAllComponentsWithoutBuild(); + snapLaneA = helper.command.getHeadOfLane('lane-a', 'comp1'); + helper.command.export(); + helper.command.createLane('lane-b'); + helper.fixtures.populateComponents(1, undefined, 'from-lane-b'); + helper.command.snapAllComponentsWithoutBuild(); + snapLaneB = helper.command.getHeadOfLane('lane-b', 'comp1'); + helper.command.export(); + helper.command.switchLocalLane('lane-a', '-x'); + beforeMerge = helper.scopeHelper.cloneLocalScope(); + }); + describe('with --no-auto-snap', () => { + before(() => { + helper.command.mergeLane('lane-b', '--no-auto-snap -x'); + }); + it('should update current lane according to the merged one', () => { + const snap = helper.command.getHeadOfLane('lane-a', 'comp1'); + expect(snap).to.equal(snapLaneB); + }); + it('should not leave the components as modified', () => { + const status = helper.command.statusJson(); + expect(status.modifiedComponents).to.have.lengthOf(0); + }); + }); + describe('with --no-snap', () => { + before(() => { + helper.scopeHelper.getClonedLocalScope(beforeMerge); + helper.command.mergeLane('lane-b', '--no-snap -x'); + }); + it('should not update current lane according to the merged one', () => { + const snap = helper.command.getHeadOfLane('lane-a', 'comp1'); + expect(snap).to.not.equal(snapLaneB); + expect(snap).to.equal(snapLaneA); + }); + it('should leave the components as modified', () => { + const status = helper.command.statusJson(); + expect(status.modifiedComponents).to.have.lengthOf(1); + }); + describe('after snapping', () => { + before(() => { + helper.command.snapAllComponentsWithoutBuild(); + }); + it('should save two parents, from the current lane and from the merged lane', () => { + const versionObj = helper.command.catComponent('comp1@latest'); + expect(versionObj.parents).to.have.lengthOf(2); + expect(versionObj.parents[0]).to.equal(snapLaneA); + expect(versionObj.parents[1]).to.equal(snapLaneB); + }); + }); + }); + }); }); diff --git a/e2e/harmony/merge-config.e2e.ts b/e2e/harmony/merge-config.e2e.ts index 8428cb25f9d..a40cc510681 100644 --- a/e2e/harmony/merge-config.e2e.ts +++ b/e2e/harmony/merge-config.e2e.ts @@ -123,7 +123,10 @@ describe('merge config scenarios', function () { helper.scopeHelper.getClonedLocalScope(mainBeforeDiverge); helper.command.snapAllComponentsWithoutBuild('--unmodified'); helper.command.export(); - helper.command.mergeLane(`${helper.scopes.remote}/dev`, '--no-snap --skip-dependency-installation --no-squash'); + helper.command.mergeLane( + `${helper.scopes.remote}/dev`, + '--no-auto-snap --skip-dependency-installation --no-squash' + ); }); it('bit status should not show the component with an issue of MergeConfigHasConflict', () => { helper.command.expectStatusToNotHaveIssue(IssuesClasses.MergeConfigHasConflict.name); @@ -163,7 +166,7 @@ describe('merge config scenarios', function () { helper.scopeHelper.reInitLocalScope(); helper.scopeHelper.addRemoteScope(); helper.command.importLane('dev'); - helper.command.mergeLane('main', '--no-snap --skip-dependency-installation'); + helper.command.mergeLane('main', '--no-auto-snap --skip-dependency-installation'); beforeConfigResolved = helper.scopeHelper.cloneLocalScope(); }); it('bit status should show the component with an issue of MergeConfigHasConflict', () => { @@ -230,7 +233,7 @@ describe('merge config scenarios', function () { helper.scopeHelper.addRemoteScope(); helper.command.importLane('dev', '--skip-dependency-installation'); beforeMerge = helper.scopeHelper.cloneLocalScope(); - helper.command.mergeLane('main', '--no-snap --skip-dependency-installation'); + helper.command.mergeLane('main', '--no-auto-snap --skip-dependency-installation'); beforeConfigResolved = helper.scopeHelper.cloneLocalScope(); }); it('bit status should show the component with an issue of MergeConfigHasConflict', () => { @@ -267,7 +270,7 @@ describe('merge config scenarios', function () { describe('merging with --auto-merge-resolve ours', () => { before(() => { helper.scopeHelper.getClonedLocalScope(beforeMerge); - helper.command.mergeLane('main', '--no-snap --skip-dependency-installation --auto-merge-resolve=ours'); + helper.command.mergeLane('main', '--no-auto-snap --skip-dependency-installation --auto-merge-resolve=ours'); }); it('should not generate the config-merge file', () => { const configMerge = helper.general.getConfigMergePath(); @@ -283,7 +286,7 @@ describe('merge config scenarios', function () { describe('merging with --auto-merge-resolve theirs', () => { before(() => { helper.scopeHelper.getClonedLocalScope(beforeMerge); - helper.command.mergeLane('main', '--no-snap --skip-dependency-installation --auto-merge-resolve=theirs'); + helper.command.mergeLane('main', '--no-auto-snap --skip-dependency-installation --auto-merge-resolve=theirs'); }); it('should not generate the config-merge file', () => { const configMerge = helper.general.getConfigMergePath(); @@ -315,7 +318,7 @@ describe('merge config scenarios', function () { helper.command.snapAllComponentsWithoutBuild('--unmodified'); helper.command.export(); - helper.command.mergeLane('dev', '--no-snap -x --no-squash'); + helper.command.mergeLane('dev', '--no-auto-snap -x --no-squash'); }); // previously, it was ignoring the previous config and only adding "ramda". it('should not remove the packages it had previously via deps set', () => { @@ -350,7 +353,7 @@ describe('merge config scenarios', function () { helper.scopeHelper.reInitLocalScope(); helper.scopeHelper.addRemoteScope(); helper.command.importLane('dev', '--skip-dependency-installation'); - helper.command.mergeLane('main', '--no-snap --skip-dependency-installation --ignore-config-changes'); + helper.command.mergeLane('main', '--no-auto-snap --skip-dependency-installation --ignore-config-changes'); beforeConfigResolved = helper.scopeHelper.cloneLocalScope(); }); it('bit status should show the component with an issue of MergeConfigHasConflict', () => { @@ -417,7 +420,7 @@ describe('merge config scenarios', function () { helper.scopeHelper.reInitLocalScope(); helper.scopeHelper.addRemoteScope(); helper.command.importLane('dev', '--skip-dependency-installation'); - helper.command.mergeLane('main', '--no-snap --skip-dependency-installation'); + helper.command.mergeLane('main', '--no-auto-snap --skip-dependency-installation'); beforeConfigResolved = helper.scopeHelper.cloneLocalScope(); }); it('bit status should show the component with an issue of MergeConfigHasConflict', () => { @@ -537,7 +540,7 @@ describe('merge config scenarios', function () { describe('when the dep was updated on the lane only, not on main', () => { describe('when the dep is in workspace.jsonc', () => { before(() => { - helper.command.mergeLane(`${helper.scopes.remote}/dev --no-squash --no-snap`); + helper.command.mergeLane(`${helper.scopes.remote}/dev --no-squash --no-auto-snap`); }); it('should change workspace.jsonc with the updated dependency', () => { const policy = helper.workspaceJsonc.getPolicyFromDependencyResolver(); @@ -548,7 +551,7 @@ describe('merge config scenarios', function () { before(() => { helper.scopeHelper.getClonedLocalScope(beforeMerges); helper.workspaceJsonc.addPolicyToDependencyResolver({ dependencies: {} }); - helper.command.mergeLane(`${helper.scopes.remote}/dev --no-squash --no-snap`); + helper.command.mergeLane(`${helper.scopes.remote}/dev --no-squash --no-auto-snap`); }); it('should auto-update the dependency according to the lane, because only there it was changed', () => { const deps = helper.command.getCompDepsIdsFromData('comp1'); @@ -583,7 +586,7 @@ describe('merge config scenarios', function () { }); describe('when the dep is in workspace.jsonc', () => { before(() => { - helper.command.mergeLane(`${helper.scopes.remote}/dev --no-squash --no-snap`); + helper.command.mergeLane(`${helper.scopes.remote}/dev --no-squash --no-auto-snap`); }); it('should not write config-merge file', () => { const conflictFile = helper.general.getConfigMergePath(); @@ -605,7 +608,7 @@ describe('merge config scenarios', function () { before(() => { helper.scopeHelper.getClonedLocalScope(afterExport); helper.workspaceJsonc.addPolicyToDependencyResolver({ dependencies: {} }); - helper.command.mergeLane(`${helper.scopes.remote}/dev --no-squash --no-snap`); + helper.command.mergeLane(`${helper.scopes.remote}/dev --no-squash --no-auto-snap`); }); it('bit status should not show a workspace issue', () => { const status = helper.command.statusJson(); @@ -681,7 +684,7 @@ describe('merge config scenarios', function () { let mergeOutput: string; before(() => { helper.scopeHelper.getClonedLocalScope(laneWs); - mergeOutput = helper.command.mergeLane(`main --no-snap -x`); + mergeOutput = helper.command.mergeLane(`main --no-auto-snap -x`); }); it('should not update workspace.jsonc', () => { const policy = helper.workspaceJsonc.getPolicyFromDependencyResolver(); @@ -723,7 +726,7 @@ describe('merge config scenarios', function () { helper.scopeHelper.reInitLocalScope(); helper.scopeHelper.addRemoteScope(); helper.command.importLane('dev', '--skip-dependency-installation'); - helper.command.mergeLane('main', '--no-snap --skip-dependency-installation --ignore-config-changes'); + helper.command.mergeLane('main', '--no-auto-snap --skip-dependency-installation --ignore-config-changes'); }); it('should not delete the previously deps set', () => { const deps = helper.command.getCompDepsIdsFromData('comp1'); diff --git a/e2e/harmony/updates-from-main-and-lane.e2e.ts b/e2e/harmony/updates-from-main-and-lane.e2e.ts index 4cc477babbc..6f4d96e7464 100644 --- a/e2e/harmony/updates-from-main-and-lane.e2e.ts +++ b/e2e/harmony/updates-from-main-and-lane.e2e.ts @@ -68,7 +68,7 @@ describe('updates from main and lane', function () { before(() => { mergeOutput = helper.command.mergeLane( 'main', - '--skip-dependency-installation --no-snap --include-non-lane-comps' + '--skip-dependency-installation --no-auto-snap --include-non-lane-comps' ); }); it('should update not only components belong to the main but also components that are available on the workspace and have updates from main', () => { diff --git a/scopes/component/merging/merge-status-provider.ts b/scopes/component/merging/merge-status-provider.ts index d87a24f83a8..ef778346314 100644 --- a/scopes/component/merging/merge-status-provider.ts +++ b/scopes/component/merging/merge-status-provider.ts @@ -22,6 +22,7 @@ export type MergeStatusProviderOptions = { mergeStrategy: MergeStrategy; ignoreConfigChanges?: boolean; shouldSquash?: boolean; + handleTargetAheadAsDiverged?: boolean; }; export const compIsAlreadyMergedMsg = 'component is already merged'; @@ -305,7 +306,12 @@ other: ${otherLaneHead.toString()}`); // component is ahead nothing to merge. return this.returnUnmerged(id, compIsAlreadyMergedMsg, true); } - if (divergeData.isTargetAhead()) { + if (!divergeData.isTargetAhead()) { + // we know that localHead and remoteHead are set, so if none of them is ahead they must be equal + return this.returnUnmerged(id, compIsAlreadyMergedMsg, true); + } + // target is ahead. + if (!this.options.handleTargetAheadAsDiverged) { // just override with the model data return { ...componentStatus, @@ -314,8 +320,7 @@ other: ${otherLaneHead.toString()}`); divergeData, }; } - // we know that localHead and remoteHead are set, so if none of them is ahead they must be equal - return this.returnUnmerged(id, compIsAlreadyMergedMsg, true); + // target is ahead and we want to treat it as diverged, continue. } // it's diverged and needs merge operation diff --git a/scopes/component/merging/merging.main.runtime.ts b/scopes/component/merging/merging.main.runtime.ts index 420f77e9cfc..61b04a0b1a5 100644 --- a/scopes/component/merging/merging.main.runtime.ts +++ b/scopes/component/merging/merging.main.runtime.ts @@ -130,7 +130,7 @@ export class MergingMain { mergeStrategy: MergeStrategy, abort: boolean, resolve: boolean, - noSnap: boolean, + noAutoSnap: boolean, message: string, build: boolean, skipDependencyInstallation: boolean @@ -148,7 +148,7 @@ export class MergingMain { consumer, bitIds, mergeStrategy, - noSnap, + noAutoSnap, message, build, skipDependencyInstallation @@ -166,7 +166,7 @@ export class MergingMain { consumer: Consumer, bitIds: ComponentID[], mergeStrategy: MergeStrategy, - noSnap: boolean, + noAutoSnap: boolean, snapMessage: string, build: boolean, skipDependencyInstallation: boolean @@ -195,7 +195,7 @@ export class MergingMain { allComponentsStatus, otherLaneId: currentLaneId, currentLane: currentLaneObject, - noSnap, + noAutoSnap: noAutoSnap, snapMessage, build, skipDependencyInstallation, @@ -210,6 +210,7 @@ export class MergingMain { allComponentsStatus, otherLaneId, currentLane, + noAutoSnap, noSnap, tag, snapMessage, @@ -220,6 +221,7 @@ export class MergingMain { allComponentsStatus: ComponentMergeStatus[]; otherLaneId: LaneId; currentLane?: Lane; + noAutoSnap?: boolean; noSnap?: boolean; tag?: boolean; snapMessage?: string; @@ -309,7 +311,7 @@ export class MergingMain { const getSnapOrTagResults = async (): Promise => { // if one of the component has conflict, don't snap-merge. otherwise, some of the components would be snap-merged // and some not. besides the fact that it could by mistake tag dependent, it's a confusing state. better not snap. - if (noSnap || leftUnresolvedConflicts || componentsHasConfigMergeConflicts) { + if (noAutoSnap || noSnap || leftUnresolvedConflicts || componentsHasConfigMergeConflicts) { return null; } if (tag) { diff --git a/scopes/lanes/merge-lanes/merge-lane.cmd.ts b/scopes/lanes/merge-lanes/merge-lane.cmd.ts index 0bef42f754c..5c8b24c1fd1 100644 --- a/scopes/lanes/merge-lanes/merge-lane.cmd.ts +++ b/scopes/lanes/merge-lanes/merge-lane.cmd.ts @@ -14,7 +14,11 @@ export class MergeLaneCmd implements Command { to merge the lane from the local scope without updating it first, use "--skip-fetch" flag. when the current and merge candidate lanes are diverged in history and the files could be merged with no conflicts, -these components will be snap-merged to complete the merge. use "no-snap" to opt-out, or "tag" to tag instead. +these components will be snap-merged to complete the merge. use "no-auto-snap" to opt-out, or "tag" to tag instead. + +when the components are not diverged in history, and the current lane is behind the merge candidate, the merge will +simply update the components and the heads according to the merge candidate. +to opt-out, use "--no-snap", the components will be written as the merge candidate, and will be left as modified. in case a component in both ends don't share history (no snap is found in common), the merge will require "--resolve-unrelated" flag. this flag keeps the history of one end and saves a reference to the other end. the decision of which end to keep is determined by the following: @@ -51,7 +55,12 @@ Component pattern format: ${COMPONENT_PATTERN_HELP}`, ['', 'ours', 'DEPRECATED. use --auto-merge-resolve. in case of a conflict, keep local modifications'], ['', 'theirs', 'DEPRECATED. use --auto-merge-resolve. in case of a conflict, override local with incoming changes'], ['', 'workspace', 'merge only lane components that are in the current workspace'], - ['', 'no-snap', 'do not auto snap after merge completed without conflicts'], + [ + '', + 'no-auto-snap', + 'do not auto snap after merge completed without conflicts of diverged components (see command description)', + ], + ['', 'no-snap', 'do not pass snaps from the other lane even for non-diverged components (see command description)'], ['', 'tag', 'auto-tag all lane components after merging into main (or tag-merge in case of snap-merge)'], ['', 'build', 'in case of snap during the merge, run the build-pipeline (similar to bit snap --build)'], ['m', 'message ', 'override the default message for the auto snap'], @@ -107,6 +116,7 @@ Component pattern format: ${COMPONENT_PATTERN_HELP}`, build, workspace: existingOnWorkspaceOnly = false, squash = false, + noAutoSnap = false, noSnap = false, tag = false, message: snapMessage = '', @@ -126,6 +136,7 @@ Component pattern format: ${COMPONENT_PATTERN_HELP}`, autoMergeResolve?: string; workspace?: boolean; build?: boolean; + noAutoSnap: boolean; noSnap: boolean; tag: boolean; message: string; @@ -157,7 +168,7 @@ Component pattern format: ${COMPONENT_PATTERN_HELP}`, } if (manual) autoMergeResolve = 'manual'; const mergeStrategy = autoMergeResolve; - if (noSnap && snapMessage) throw new BitError('unable to use "no-snap" and "message" flags together'); + if (noAutoSnap && snapMessage) throw new BitError('unable to use "no-snap" and "message" flags together'); if (includeDeps && !pattern && !existingOnWorkspaceOnly) { throw new BitError(`"--include-deps" flag is relevant only for --workspace and --pattern flags`); } @@ -179,6 +190,7 @@ Component pattern format: ${COMPONENT_PATTERN_HELP}`, ours, theirs, existingOnWorkspaceOnly, + noAutoSnap, noSnap, snapMessage, keepReadme, diff --git a/scopes/lanes/merge-lanes/merge-lanes.main.runtime.ts b/scopes/lanes/merge-lanes/merge-lanes.main.runtime.ts index 90610e844ae..c37747a57cb 100644 --- a/scopes/lanes/merge-lanes/merge-lanes.main.runtime.ts +++ b/scopes/lanes/merge-lanes/merge-lanes.main.runtime.ts @@ -42,6 +42,7 @@ export type MergeLaneOptions = { mergeStrategy: MergeStrategy; ours?: boolean; theirs?: boolean; + noAutoSnap?: boolean; noSnap?: boolean; snapMessage?: string; existingOnWorkspaceOnly?: boolean; @@ -110,6 +111,7 @@ export class MergeLanesMain { const { mergeStrategy, + noAutoSnap, noSnap, tag, snapMessage, @@ -204,6 +206,7 @@ export class MergeLanesMain { ignoreConfigChanges, shouldSquash, mergeStrategy, + handleTargetAheadAsDiverged: noSnap, }, currentLane, otherLane @@ -275,6 +278,7 @@ export class MergeLanesMain { allComponentsStatus, otherLaneId, currentLane, + noAutoSnap, noSnap, tag, snapMessage,