Skip to content

fix(push): force rewrites without fetching discarded tips - #575

Closed
forhappy wants to merge 2 commits into
codex/staging-lint-expectationsfrom
codex/capsule-force-push
Closed

forhappy wants to merge 2 commits into
codex/staging-lint-expectationsfrom
codex/capsule-force-push

Conversation

@forhappy

@forhappy forhappy commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

A clone that diverges after another writer advances the remote cannot force-push unless it first fetches the discarded remote tip. Capsule admission rejects missing local ancestry as stale info; visibility construction also requires that old tip.

Allow unavailable ancestry for an explicit force or matched lease only when receive policy permits rewrites. Preserve lease checks, hard probe errors and the conditional old-ref publication boundary. Proven fast-forwards and rewrites with locally available old tips retain incremental visibility; rewrites missing their old tip use the existing complete replacement-closure format so discarded objects lose authorization without reading old history. Pack and LFS exclusions already use only locally available tips.

Stacked on #573. Draft; no merges requested. No format, dependency, lockfile or configuration changes. Requested benchmark audit reports are excluded.

Validation:

  • Existing RustFS ref matrix reproduces the exact stale-info rejection with the frozen predecessor release, matching CI run 38675468949. Importing only the missing tip from its local source makes the same binary succeed.
  • Exact extracted visibility helper and its canonical object-walk callee, linked to locked release dependency types: unchanged code fails; patched code passes and matches native Git's complete object set, excluding the discarded tip. This proves the helper, not the whole updated CLI.
  • Added six real-Git/capsule cases for ordinary, forced, matched/stale lease and denied force/lease updates. Successful cases check committed refs, old-tip invisibility, independent pack installation and connectivity fsck. Full consumer test run is pending CI.
  • Extended the existing RustFS ref matrix to prove the missing local tip and exercise native and helper force pushes without fetching.
  • Eleven source-isolation tests pass. Rust formatting, Python syntax and diff whitespace checks pass.
  • Production adds a bounded lookup through the existing local-tip selector; existing known-tip removal evidence stays unchanged. Most added lines exercise the shared publication owner.

Evidence map: native CLI cmd/push.rs and remote helper both call capsule_push::run; admission calls is_ancestor and shared check_ref_update; visibility calls the canonical bounded object walk and metadata-owned replacement encoder. Read-side readiness validates transaction old/new identity and applies replacement authorization. Pack and LFS publication independently filter unavailable remote exclusions. The retired legacy pipeline also permits forced non-fast-forwards; current origin/main has no capsule push module, so it cannot establish this v2 behavior.

Is this the best fix? The shared capsule owner now separates force authorization from optional local ancestry and uses the existing replacement representation. Fetching discarded history solely to authorize its removal would preserve the bug's unnecessary dependency. Broad CI, the full current-source RustFS canary and final-source 10-GiB qualification remain required.

Updated-source qualification is pinned to f6c35dcc9ca61389c5bdab18f336f77e26a75cc2. The first dispatched provider run was cancelled while queued because its source was superseded by the known-tip delta correction. No terminal test failure is claimed from that cancellation.

Current CI: protocol/unit and cross-platform run and full RustFS provider/canary run are queued at the updated source. The earlier Git-current parent failure is separately traced to mirror_lfs_discovery_check reading an assumed loose object path that does not exist; it is repaired separately in draft #576 without waiving the checksum assertion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant