Skip to main content

write_ref_recording_history

Function write_ref_recording_history 

Source
pub fn write_ref_recording_history(
    layout: &RepoLayout,
    branch: &str,
    condition: RefWriteCondition,
    new_hash: &Hash,
) -> Result<(), RefError>
Expand description

CLI-side ref-write helper that records every advance in the branch’s history MMR when history-mmr is enabled.

Behaviour matrix:

  • Default build (no history-mmr) — exactly equivalent to refs::update_ref(mkit_dir, branch, condition, new_hash).
  • --features history-mmr — takes the refs-history.lock repo lock, THEN opens a journaled CommitHistory for branch under <mkit_dir>/history/ (lock-then-open, not the reverse — see mkit_core::refs::open_and_update_ref_with_history_and_backfill’s doc comment for why), performs the CAS ref-write, appends new_hash to the MMR, and sync()s the journal before returning. The journal survives SIGKILL immediately after the call returns. See mkit-core::refs::open_and_update_ref_with_history_and_backfill and SPEC-HISTORY-PROOF §4 for the contract.

If the journal is empty but branch already has a ref value on disk (a v0.1.x-era repo enabling history-mmr for the first time, or a crash on the branch’s very first tracked write), this backfills the full known chain via mkit_core::history::rebuild_from_chain before proceeding — SPEC-HISTORY-PROOF §4.5. The empty-journal check AND the backfill loop run inside mkit_core::refs::update_ref_with_history_and_backfill’s refs-history.lock critical section (issue #638 / INV-18): running them before the lock (as this used to) let two ref-only writers on the same never-before-journaled branch — e.g. two concurrent update-ref calls, which deliberately skip the worktree lock — both observe an empty journal and both independently backfill, corrupting the journal’s leaf positions.

All CLI subcommands that move a branch ref MUST funnel through this helper rather than calling refs::write_ref or refs::update_ref directly. Detached-HEAD writes (refs::write_head_detached) are not history-tracked: the per-branch journal is keyed on the branch name, and detached HEADs have none.