Storage protocol for git objects, keyed by binary SHA-1.
Implemented by Exgit.ObjectStore.Memory (in-heap),
Exgit.ObjectStore.Disk (git's on-disk layout), and
Exgit.ObjectStore.Promisor (lazy, fetch-on-demand).
Stores are pure values: every write (put/2, import_objects/2,
close_write/2) returns the updated store, which the caller must
thread forward. Reads never mutate.
Summary
Functions
Abort the write session and release any associated resources (open ports,
temp files, etc.) without persisting the object. Always returns :ok.
Finalise the write session: compute the object SHA, persist the object,
and return the updated store. Returns {:ok, sha, updated_store}.
Uncompressed byte size of an object WITHOUT materializing its content.
Open a streaming write session for an object of type and expected_size
bytes (the declared uncompressed size from the pack header).
Append a chunk of uncompressed content to the in-progress write session.
Returns {:ok, updated_handle}.
Types
@type t() :: term()
All the types that implement this protocol.
Functions
Abort the write session and release any associated resources (open ports,
temp files, etc.) without persisting the object. Always returns :ok.
Finalise the write session: compute the object SHA, persist the object,
and return the updated store. Returns {:ok, sha, updated_store}.
@spec get(t(), binary()) :: {:ok, Exgit.Object.t()} | {:error, term()}
@spec object_size(t(), binary()) :: {:ok, non_neg_integer()} | {:error, :not_found | :not_local | term()}
Uncompressed byte size of an object WITHOUT materializing its content.
The point is a constant-memory size check: callers can decide whether a blob is too large to read before paying to inflate it into the heap.
Returns {:ok, byte_count} when the store can answer, or:
{:error, :not_found}— the object is genuinely absent from the store.{:error, :not_local}— a meaningful, non-fatal result for lazy stores (Promisor): it means "knowing this size requires a network fetch", so the caller can opt in rather than have a multi-GB fetch triggered behind a size check.{:error, term()}— store-specific failure (e.g. a corrupt loose object on disk).
@spec open_write(t(), Exgit.Object.object_type(), non_neg_integer()) :: {:ok, term()} | {:error, term()}
Open a streaming write session for an object of type and expected_size
bytes (the declared uncompressed size from the pack header).
Returns {:ok, handle} where handle is an opaque term, or
{:error, :not_supported} for stores that do not implement the streaming API.
@spec put(t(), Exgit.Object.t()) :: {:ok, binary(), t()}
Append a chunk of uncompressed content to the in-progress write session.
Returns {:ok, updated_handle}.