Replicates ordinary bare mirrors through an object store.
The intended scheduler loop is: restore when a local mirror is absent, fetch into the ordinary bare repository, then publish its new snapshot. A stored bundle is a transport artifact: restore it; do not try to open it as a shared filesystem repository. Replication deliberately does not provide shared-POSIX-filesystem reader/writer semantics.
Publish and restore share Gitility.Fetch's per-expanded-path lease. A
contended call returns retryable :busy immediately. Conditional-write
loss returns retryable :conflict, while matching tips return
:not_newer. A transport failure during PUT can be indeterminate because
the store may have committed before the connection failed; Gitility performs
one HEAD reconciliation and marks an unresolved result with
details.indeterminate. Re-running publish is always safe.
The timeout bounds object-store callbacks, lock-manager interaction, staged
section copying, and the restore deep-check loop. Bundle.write/2,
Bundle.verify/1, repository open, and the native ref transaction run to
completion; the deadline is checked immediately after each. Temporary
files and restore stages are siblings of the mirror, so the final rename is
on one filesystem. S3 publication is a single PUT and therefore has a 5 GiB
limit.
What restore verifies
Restore verifies the container and every section sha256, associates every
pack with its real index by the Git trailers and filename checksum, runs the
local store's pack/index checksum scan, proves that every ref target exists
with its recorded kind, validates supplied peels, and checks HEAD
coherence. It does not perform a reachability walk like git fsck; closed
packs are the publisher's responsibility, and the normal restore → fetch
loop heals missing closure from an untrusted publisher.
Gitility-owned errors, results, state, inspection, and log lines never retain adapter/provider terms or credentials. Req and Finch telemetry are outside that boundary; do not attach Finch telemetry handlers that log requests for the gitility pool.
Strict publication and restore reject ref names containing a path component longer than 255 bytes. This keeps accepted bundles round-trippable on the filesystems used by gix's ref transaction.
Summary
Functions
Publishes one consistent bare-mirror snapshot with a conditional write.
Restores an object-store bundle as an ordinary gc-safe bare repository.
Types
Functions
@spec publish(Path.t(), store(), binary(), keyword()) :: {:ok, Gitility.Mirror.Receipt.t()} | {:ok, :not_newer} | {:error, Gitility.Error.t()}
Publishes one consistent bare-mirror snapshot with a conditional write.
@spec restore(store(), binary(), Path.t(), keyword()) :: {:ok, Gitility.Mirror.Restore.t()} | {:error, Gitility.Error.t()}
Restores an object-store bundle as an ordinary gc-safe bare repository.