A repository is just an ODB plus an optional RefDB.
It exists to resolve selectors — names for commits — into pinned
Gitility.Snapshots. Nothing else in the library takes a repository:
every query takes a snapshot, and a snapshot needs only an ODB and a
commit ID.
init_bare/2 creates a SHA-1 bare repository with automatic garbage
collection and maintenance disabled. Every bare directory created by
Gitility has that gc-safe configuration; Gitility does not retrofit or
otherwise change repositories it did not create. Initialisation shares the
expanded-path lease used by fetch, publish, and restore; contention returns
retryable :busy immediately.
Opening is intentionally cheap. The first query in a fresh process also starts and warms the native runtime and may take roughly 700 ms; subsequent queries reuse it.
Selectors
Safe selectors resolve a name through the repository's stores:
{:oid, oid_or_hex} # no refs needed
{:ref, "refs/pull/481/head"}
{:branch, "main"} # expands to refs/heads/main
{:tag, "v1.2.0"} # expands to refs/tags/…, peels annotated tags
:head{:revspec, string} is reserved for a future opt-in advanced selector.
Gitility 0.x always rejects it with :unsupported_operation.
Summary
Types
A commit selector — see the moduledoc.
A repository handle: object store plus optional ref store.
Functions
Composes independently-created stores into a repository. The stores must
share a runtime (:runtime_mismatch otherwise).
Creates a gc-safe bare SHA-1 repository.
Opens a local repository directory — bare or normal, though queries never read worktree files either way.
Resolves a selector and pins it as an immutable snapshot.
Types
@type selector() :: {:oid, Gitility.OID.t() | String.t()} | {:ref, binary()} | {:branch, binary()} | {:tag, binary()} | :head | {:revspec, String.t()}
A commit selector — see the moduledoc.
@type t() :: %Gitility.Repository{ odb: Gitility.ODB.t(), ref_error: Gitility.Error.t() | nil, refs: Gitility.RefDB.t() | nil }
A repository handle: object store plus optional ref store.
Functions
@spec from_stores(keyword()) :: {:ok, t()} | {:error, Gitility.Error.t()}
Composes independently-created stores into a repository. The stores must
share a runtime (:runtime_mismatch otherwise).
Store identity is otherwise deliberately not compared. Cross-repository composition — for example, refs from one repository with an ODB from another — is the caller's responsibility and is not detected by Gitility.
Options
:odb(required) — aGitility.ODBhandle.:refs— aGitility.RefDBhandle; omit for an ODB-only repository (only{:oid, _}selectors will resolve).
@spec init_bare( Path.t(), keyword() ) :: :ok | {:error, Gitility.Error.t()}
Creates a gc-safe bare SHA-1 repository.
The destination must be absent or an empty directory. Creation is not
idempotent: a non-empty destination is rejected and never modified. Parent
directories are created as needed. hash: :sha256 is reported as
:unsupported_hash before the filesystem is touched. The :gitility
application must be started so creation can acquire the shared
Gitility.Fetch.Locks lease; if that process is not running, creation
returns a non-retryable :backend_error.
@spec open( Path.t(), keyword() ) :: {:ok, t()} | {:error, Gitility.Error.t()}
Opens a local repository directory — bare or normal, though queries never read worktree files either way.
Options
:require_bare— reject a non-bare repository (defaultfalse).:object_cache_bytes— native object cache ceiling (default 64 MiB).:verify_pack_checksums— deep-check pack and index checksums before the first object read (defaultfalse).:runtime— theGitility.Runtimeto attach to (default: shared).
Example
{:ok, repo} =
Gitility.Repository.open("/srv/git/acme/widgets.git", require_bare: true)
{:ok, snapshot} = Gitility.Repository.snapshot(repo, {:branch, "main"})
@spec snapshot(t(), selector(), keyword()) :: {:ok, Gitility.Snapshot.t()} | {:error, Gitility.Error.t()}
Resolves a selector and pins it as an immutable snapshot.
Resolution happens once, here: the returned snapshot records the commit and root tree IDs and never moves, no matter what the underlying refs do afterwards.