feat(lanes): allow --squash on diverged components#10387
Open
davidfirst wants to merge 1 commit into
Open
Conversation
Previously `bit lane merge <other-lane> --squash` threw when components were diverged in history. Now it produces a single-parent merge snap with the dropped other-lane head captured in Version.squashed metadata. This keeps the merged lane's history self-contained on its own scope, so exporting after merging from a foreign scope does not pull that scope's intermediate snap objects. The existing VersionHistory graph already treats squashed.previousParents as edges, so subsequent re-merges from the same source lane correctly identify the previously-merged head as the diverge base.
Contributor
There was a problem hiding this comment.
Pull request overview
Enables bit lane merge <other-lane> --squash to work even when component histories are diverged, by creating a single-parent merge snap and recording the dropped foreign head in Version.squashed metadata (preventing cross-scope history pull-in on export).
Changes:
- Thread a
shouldSquashflag through lane-merge → merge engine → snap creation, and persist it onUnmergedComponent. - Adjust squash handling so diverged components no longer throw in the pre-squash path; instead they’re handled at snap-creation time via squashed metadata.
- Add comprehensive E2E coverage for single-scope and multi-scope diverged squash, re-merge behavior, and non-squash sanity checks.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| scopes/lanes/merge-lanes/merge-lanes.main.runtime.ts | Stops throwing on diverged --squash and passes shouldSquash through to the merge engine. |
| scopes/component/merging/merging.main.runtime.ts | Propagates shouldSquash into UnmergedComponent entries for diverged merges. |
| scopes/component/snapping/snapping.main.runtime.ts | On snap creation, uses shouldSquash to record Version.squashed metadata and avoid adding the foreign head as a second parent. |
| components/legacy/scope/lanes/unmerged-components.ts | Extends UnmergedComponent schema with optional shouldSquash. |
| e2e/harmony/lanes/merge-lanes-squash-diverge.e2e.ts | Adds E2E tests covering diverged squash scenarios and regressions. |
Comment on lines
+1116
to
+1120
| version.setSquashed({ previousParents, laneId: unmergedComponent.laneId }, version.log); | ||
| this.logger.debug( | ||
| `sources.addSource, unmerged component "${component.name}". squash-on-diverged: dropping parent ${unmergedComponent.head.hash}` | ||
| ); | ||
| version.log.message = version.log.message || UnmergedComponents.buildSnapMessage(unmergedComponent); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
bit lane merge <other-lane> --squashpreviously threw when components were diverged in history, forcing users to either do a two-way merge dance or fall back to--no-squash. With--no-squashon large lanes hosted in different scopes, exporting after the merge pulls the other scope's full snap history into the merging scope, which can blow up memory on both client and remote.What
Diverged components under
--squashnow produce a single-parent merge snap. The dropped foreign head is recorded inVersion.squashed(previousParents + laneId), so:bit logfrom a fresh consumer of scope-a is clean (noParentNotFoundwalking into scope-b).VersionHistorygraph treatssquashed.previousParentsas edges (version-history.ts:199, 263), so diverge calculation finds the last-merged head as the base instead of re-merging history that was already squashed.No remote-side changes were needed.
Implementation
UnmergedComponentgainsshouldSquash?: boolean.mergeSnaps/applyVersionMultiple/applyVersionthreadshouldSquashthrough and set the flag on the unmerged entry when divergent.merge-lanes.main.runtime.tsno longer throws on diverged — it returns false so the snap-time path handles it.snapping.main.runtime.ts), the unmerged-component branch checksshouldSquash: if true, callssetSquashedwith both pre-squash parents and skipsaddParentof the foreign head.Test plan
E2e tests in
e2e/harmony/lanes/merge-lanes-squash-diverge.e2e.ts(21 cases, all passing):bit logbit logandbit statusdon't throw--squashstill produces two-parent merge snap