ref:main
feat: git lfs — pointer, store, batch, transfer, locks #22
merged
cole.christensen@gmail.com wants to merge
feat/lfs
into main
No CI
Summary
Full Git LFS (spec v1) support, closes #38. Exposed as pure request/response modules that mirror the existing `UploadPack`/`ReceivePack` style — no HTTP server is introduced; consumers wire the handlers into their own routing.
What’s in
- `ExGitObjectstore.Lfs.Pointer` — parser/emitter with strict spec-v1 validation (version-first, alphabetical keys, sha256-only OIDs, canonical decimal size, trailing LF).
- `ExGitObjectstore.Lfs.Store` — behaviour parallel to `Storage`, keyed by SHA256. Streaming `put/4` verifies the observed SHA256 matches the claimed OID; on mismatch the write is discarded. Backends: Memory, Filesystem (2+2 fanout, atomic rename), and S3 (multipart upload with optional presigned URLs). Shared conformance macro at `ExGitObjectstore.Test.LfsStoreConformance` exercises every backend identically.
- `ExGitObjectstore.Lfs.Batch` — Batch API returning spec-compliant upload/download/verify actions. Uses presigned URLs when the backend supports them; falls back to library-served URLs for Filesystem/Memory.
- `ExGitObjectstore.Lfs.Transfer` — basic-transfer handlers for `GET/PUT /objects/:oid` and `POST /objects/:oid/verify`.
- `ExGitObjectstore.Lfs.Locks` — v1 locks API (create, list, verify, unlock with owner/force).
- Telemetry at `[:ex_git_objectstore, :lfs, :batch | :transfer | :lock]`.
- `Repo` gains optional `:lfs_storage` alongside `:storage`.
- CHANGELOG entry under `[Unreleased]`.
- Anvil requirements REQ-LFS-001…006 created; tests carry `@moduletag requirements: […]`.
Test plan
- 91 new LFS tests pass (14 S3 tests excluded without MinIO)
- Full suite: 891 tests, 0 failures
- `mix credo –strict` clean for all new code
- `mix format` clean
- `anvil requirement status` passes
- Manual interop against `git lfs` client (follow-up, not in PR)
🤖 Generated with Claude Code
Created Apr 20, 2026 at 06:14 UTC
| Merged Apr 20, 2026 at 13:33 UTC
by
cole.christensen@gmail.com