# `Exgit.ObjectStore.Disk`
[🔗](https://github.com/ivarvong/exgit/blob/v0.1.0/lib/exgit/object_store/disk.ex#L1)

On-disk git object store — reads and writes objects from
`<root>/objects/` in git's standard layout: loose objects under
`aa/bbbb...` and packed objects via `pack-*.{pack,idx}`.

Loose-object reads wrap `:zlib.uncompress/1` in `try/rescue` so
corrupt or bit-rotted files return `{:error, :zlib_error}`
rather than crashing the caller. Pack lookups use `:file.pread/3`
with the idx offset so single-object latency is independent of
pack size.

Content-addressed SHA verification runs on every loose-object
read — see `verify_sha/2`. Pack reads rely on the pack's own
content-addressed lookup via idx; the SHA is verified implicitly
at inflate time.

# `t`

```elixir
@type t() :: %Exgit.ObjectStore.Disk{root: Path.t()}
```

# `delete_object`

```elixir
@spec delete_object(t(), binary()) :: :ok | {:error, :not_found}
```

# `get_object`

```elixir
@spec get_object(t(), binary()) ::
  {:ok, Exgit.Object.t()} | {:error, :not_found | term()}
```

# `has_object?`

```elixir
@spec has_object?(t(), binary()) :: boolean()
```

# `list_objects`

```elixir
@spec list_objects(t()) :: [binary()]
```

# `new`

```elixir
@spec new(Path.t()) :: t()
```

# `object_size`

```elixir
@spec object_size(t(), binary()) :: {:ok, non_neg_integer()} | {:error, term()}
```

Uncompressed object size without materializing the object.

For a loose object this reads and inflates only enough compressed
bytes to cover the header (`"<type> <size>\0"`) — constant memory
AND constant I/O, no matter how large the blob. Packed objects fall
back to a full read (the delta chain must be resolved to know the
final size), so this is cheap for loose objects and O(object) for
packed ones.

# `put_object`

```elixir
@spec put_object(t(), Exgit.Object.t()) :: {:ok, binary()} | {:error, term()}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
