Exgit.Repository (exgit v0.1.0)

Copy Markdown View Source

A git repository value.

Carries an object store, a ref store, optional on-disk path and config, and a :mode that distinguishes eager-fully-populated repositories from lazy ones.

:mode

The :mode field is part of the public API. It has two values:

  • :eager — every reachable object is locally available. Streaming FS operations (FS.walk/2, FS.grep/4) can iterate without triggering network fetches or producing silent empty results.

  • :lazy — backed by an ObjectStore.Promisor; some objects are fetched on demand from the transport. Streaming FS operations would either blow up (unbounded fetches mid-stream) or silently skip missing objects, so they raise ArgumentError. Strict FS operations (FS.read_path/3, FS.ls/3, FS.stat/3, FS.write_path/4) work because they fetch as needed and return {:ok, result, repo} for cache threading.

Convert a :lazy repo to :eager via materialize/2.

:mode defaults to :eager when constructing via new/3 without an explicit :mode opt, so existing callers are unaffected.

Summary

Types

Structured memory usage report for a repository.

t()

Functions

Convert a :lazy (Promisor-backed) repo into an :eager (Memory-backed) one, fetching every reachable object from reference through the Promisor's transport first.

Returns a structured memory-usage report for repo.

Types

memory_report()

@type memory_report() :: %{
  object_count: non_neg_integer() | :unknown,
  cache_bytes: non_neg_integer() | :unknown,
  commit_count: non_neg_integer() | :unknown,
  tree_count: non_neg_integer() | :unknown,
  blob_count: non_neg_integer() | :unknown,
  tag_count: non_neg_integer() | :unknown,
  max_cache_bytes: non_neg_integer() | :infinity,
  mode: mode(),
  backend: module()
}

Structured memory usage report for a repository.

  • :object_count — total distinct objects in the cache
  • :cache_bytes — compressed bytes stored (what :max_cache_bytes bounds)
  • :commit_count, :tree_count, :blob_count, :tag_count — count of each object kind
  • :max_cache_bytes — configured cap (:infinity if unbounded)
  • :mode — repo mode (:eager or :lazy)
  • :backend — the object-store module

Counts and :cache_bytes are :unknown for backends that can't be introspected (Disk, user-defined stores).

mode()

@type mode() :: :eager | :lazy

t()

@type t() :: %Exgit.Repository{
  config: Exgit.Config.t() | nil,
  mode: mode(),
  object_store: term(),
  path: Path.t() | nil,
  ref_store: term()
}

Functions

materialize(repo, reference)

@spec materialize(t(), String.t() | binary()) :: {:ok, t()} | {:error, term()}

Convert a :lazy (Promisor-backed) repo into an :eager (Memory-backed) one, fetching every reachable object from reference through the Promisor's transport first.

After materialization, the repo can be freely passed to streaming operations (FS.walk/2, FS.grep/4) without any special setup — the :mode is flipped to :eager as part of the same call.

On a repo that is already :eager, materialize returns the repo unchanged.

memory_report(repository)

@spec memory_report(t()) :: memory_report()

Returns a structured memory-usage report for repo.

Designed for operational monitoring — agent hosts can poll this between operations to track peak memory, detect unexpected cache growth, and alert when a configured cap is approached.

Returns consistent shape across all object-store backends (Memory, Disk, Promisor, SharedPromisor); counts and :cache_bytes for backends without per-type bookkeeping (like Disk) are :unknown. All keys are always present.

Examples

iex> {:ok, repo} = Exgit.clone(url, lazy: true)
iex> {:ok, repo} = Exgit.FS.prefetch(repo, "HEAD", blobs: true)
iex> Exgit.Repository.memory_report(repo)
%{
  object_count: 17_500,
  cache_bytes: 4_213_780,
  commit_count: 0,
  tree_count: 8_290,
  blob_count: 9_210,
  tag_count: 0,
  max_cache_bytes: :infinity,
  mode: :lazy,
  backend: Exgit.ObjectStore.Promisor
}

Use in an agent

repo
|> Exgit.Repository.memory_report()
|> log_to_your_observability_stack()

new(object_store, ref_store, opts \\ [])

@spec new(term(), term(), keyword()) :: t()