Gitility.Mirror (Gitility v0.5.0)

Copy Markdown View Source

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

store()

@type store() :: {module(), term()}

Functions

publish(mirror_dir, store, key, opts \\ [])

@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.

restore(store, key, mirror_dir, opts \\ [])

@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.