Repository replication — guide
How to copy a repository's artifacts from one holger store into another. The replicator reads only from the source and writes only into the destination, and it is idempotent by content id — a re-run over an unchanged source copies nothing. It is a dry-run preview unless you pass --execute.
CLI: replicate between two stores
Both the source and the destination are ordinary holger RON configs (the same files holger-server start uses). They can be two entirely separate file-backed stores on the same laptop — no network, no running server needed.
holger-server replicate --from FROM.ron --to TO.ron # dry-run preview
holger-server replicate --from FROM.ron --to TO.ron --execute # actually copy
holger-server replicate --from FROM.ron --to TO.ron --repo mirror --execute
holger-server replicate --from FROM.ron --to TO.ron --execute --limit 100
--from— SOURCE config (read-only here; only listed + fetched).--to— DESTINATION config (its repos must be writable).--repo R— restrict to a single source repo name. Omit ⇒ every source repo that has a same-named destination repo.--execute— actually copy. Omit for a preview (reports what would copy, writes nothing).--limit N— cap artifacts examined per repo (0 = unlimited).
Repos are paired by name: source repo mirror replicates into destination repo mirror. A source repo with no same-named destination is logged and skipped.
Reading the output
replicate FROM.ron → TO.ron [execute]: examined 2, copied 2, skipped 0, would-copy 0, failed 0
[COPIED] mirror→mirror -/serde@1.0.0
[COPIED] mirror→mirror -/tokio@1.40.0
COPIED— written into the destination this run.skip— already present in the destination by content id (idempotent).would— a dry run would copy this (nothing written).FAIL— could not replicate (source unreadable, or destination read-only); the line carries the reason and the command exits non-zero.
Run it twice with --execute: the second run reports copied 0, skipped N — the proof it is a no-op over an unchanged source.
gRPC: replicate within one running server
ReplicationService.Replicate copies between two repos on one server:
rpc Replicate(ReplicateRequest) returns (ReplicateResponse);
// from_repo (source, read-only) · to_repo (dest, writable) · execute · limit
The destination repo is admin-gated (fail-closed under a configured role policy, like promotion). from_repo == to_repo is rejected. The response carries examined / copied / skipped / would_copy / failed / copied_bytes / truncated / complete.
Guarantees
- The destination ends up holding every source artifact, byte-identical (a dropped or garbled copy is a hard test failure).
- A read-only destination fails closed — every copy is reported as a failure, nothing is silently dropped, and the CLI exits non-zero.
- Nothing on the source is ever modified.