fix(merge): preserve state when source table versions lag target - #630
Merged
Conversation
5 tasks
aaltshuler
force-pushed
the
codex/repro-untouched-table-merge
branch
from
September 7, 2026 12:49
a8aa5ea to
47cb4c0
Compare
5 tasks
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.
What & why
A fast-forward merge can report success while retaining stale rows when the source table's native Lance version is lower than or equal to the target's. In the reproduced round trip,
mainhas three edges at version 5 andfeaturehas two at version 20. Mergingmainintofeature, editing only a node, and merging back silently reducesmainto two edges. A second regression returns age 47 after successfully merging age 50.Native version counters belong to individual branches, but the current manifest projection selects the greatest registered version per table identity. Route these adoptions through the existing target-lineage delta writer; retain the complete target entry when row comparison proves the delta empty. Blob preflight uses the same routing rule, and existing recovery owns every required table effect before the single graph publication.
Backing issue / RFC
Checklist
Rebase and GQT verification — 2026-09-07
Rebased onto current
mainat5f94a7419f574d05f87b9ee593a7102f6fe14491; #662 and #668 retain their stacked bases.branch_round_trip_preserves_newer_values.gqtandbranch_round_trip_preserves_untouched_edges.gqt, with observedred_onprovenance. On the clean main runner they fail with age 47 instead of 50 and two edges instead of three, respectively.47cb4c02: all 50 GQT cases passed. Each new case completes in under 0.5 s locally.Reported GQT results use separately rebuilt and hashed runners for each stack revision; a stale shared-target attempt was discarded and the engine/runner rebuilt. Earlier verification below belongs to its original source revisions, not this rebase.
Original implementation verification (before this rebase)
Cargo commands used a shared
CARGO_TARGET_DIR.cargo test -p omnigraph-engine --locked --test branching branch_merge_ -- --nocapture— 20 passed, two new regressions failed as predicted. The clean owning baseline passed before test edits.cargo test --workspace --locked --no-fail-fast --features omnigraph-engine/failpoints,omnigraph-cluster/failpoints— 2,939 passed, 21 failed, 24 ignored on the initial run. Twenty CLI parity failures came from the harness looking in this worktree'starget/debugwhile builds used the shared cache. After connecting the ignored target path, the complete same-binary parity rerun passed (21 tests). The remaining benchmark process-cleanup test passed on an isolated same-binary rerun; its worker does not invoke merge code.cargo clippy --workspace --all-targets --locked -- -D warnings -W clippy::dbg_macro— passed.cargo clippy --workspace --all-targets --locked --features omnigraph-engine/failpoints,omnigraph-cluster/failpoints -- -D warnings -W clippy::dbg_macro— passed.cargo fmt --all --check,git diff --check,bash scripts/check-agents-md.sh,python3 scripts/check-docs.py, andpython3 scripts/check-workflow-action-pins.py— passed.Notes for reviewers
The new
.gqtcases cover scalar rollback and untouched-edge preservation through branch round trips and reopen. Rust owners retain the native-version matrix, native pins, exact stored-edge identities, and recovery checks. Empty-delta assertions check both the retained table registration and unchanged physical HEAD.The fresh-fork-after-insert control passes before this fix. This PR fixes the reproduced existing-branch round trip; it does not establish the exact cause of the original fresh-fork report. The indexed lazy-target cases use first-generation forks; the separate clone-of-clone index-path defect remains covered by
second_generation_branch_index_reads_fail_upstream(Lance #7840).