pub async fn mark(
store: &dyn ObjectStore,
prefix: &str,
opts: MarkOpts,
) -> Result<MarkOutcome, PackchainError>Expand description
Run the mark phase: snapshot every pack on the bucket, then every chain, then write a tombstone naming the orphans.
prefix is the repository prefix without leading or trailing
slashes — pass an empty string for bucket-root repositories.
§Ordering
Listings run packs-first, chains-second (issue #135). The reverse
order races a concurrent push that uploads a new pack between the
two listings and commits its chain.json between the chain list
and the pack list: the new pack would appear in the on-bucket set
but not in the referenced set, producing a false-positive tombstone.
Packs-first inverts the staleness: the referenced set is always at
least as fresh as the on-bucket set, so a pack appearing in the
snapshot is either also in the chain set (saved) or genuinely
orphan at some point during the mark (correctly tombstoned, with
the grace window covering in-flight pushes).
§Errors
- Any chain.json that fails to parse aborts the mark with
PackchainError::ParseJson/PackchainError::InvalidSha/PackchainError::UnsupportedSchemaVersion. The tombstone is not written. Operators must repair the bad chain (or remove it) before re-running. PackchainError::Store/PackchainError::Iofor transport or local-I/O failures.
§Example
use git_remote_object_store::Remote;
use git_remote_object_store::packchain::gc::{MarkOpts, mark};
let remote = Remote::connect("s3+https://bucket/repo?engine=packchain").await?;
let outcome = mark(remote.store(), remote.prefix(), MarkOpts::default()).await?;
println!(
"{} orphan pack(s) tombstoned (run id {})",
outcome.orphan_count, outcome.run_id,
);