fangorn/ex_git_objectstore
public
ref:main
feat: git lfs (pointer, store, batch API, transfer, locks) #38
closed
Opened by cole.christensen@gmail.com
Links
No links yet.
Add full Git LFS support: pointer parsing, object storage abstraction with FS/S3/Memory backends parallel to the existing Storage behaviour, Batch API, object transfer, locks API, and SHA256 verification. Exposed as pure request/response modules consistent with the existing UploadPack/ReceivePack style (no HTTP server in-tree).
Scope
- Pointer blob parser/emitter (spec v1) with strict validation
ExGitObjectstore.Lfs.Storebehaviour, keyed by SHA256- Backends:
Lfs.Store.Filesystem,Lfs.Store.S3,Lfs.Store.Memory— parity with existingStorage.*(same config/prefix style) - Batch API (
POST /objects/batch) — upload/download action generation, presigned-URL mode for S3 (direct-to-backend), streamed mode for Filesystem/Memory - Object transfer (
GET/PUT /objects/:oid,POST /objects/:oid/verify) — streaming, SHA256 verified on PUT - Locks API v1 (
POST /locks,POST /locks/:id/unlock,GET /locks,POST /locks/verify) - Auth hook pattern consistent with existing protocol modules (caller enforces; library provides request context)
- Telemetry spans parallel to existing fetch/push spans
Acceptance Criteria
- Pointer parser round-trips (parse then emit == input) for all spec-compliant pointer blobs
- Parser rejects malformed pointers (wrong version, non-sha256 OID, non-integer size, unknown keys in non-canonical position)
-
Lfs.Storebehaviour defined; three backends implement it with passing shared conformance tests - Batch API returns spec-compliant JSON for upload, download, verify operations
- Transfer handlers stream multi-GB blobs without loading into memory (verified by test with >RAM-safe-size stream)
- SHA256 mismatch on PUT returns 422 and does not persist
- Locks API passes basic create/list/unlock/verify round-trips
- S3 backend: batch returns presigned URLs; Filesystem/Memory: batch returns library-served URLs
- Auth hook invoked per request; rejection surfaces as 401/403
- Telemetry events emitted:
[:ex_git_objectstore, :lfs, :batch],[:transfer],[:lock] - CHANGELOG updated in feature branch before PR
- Requirements defined via
anvil requirementandanvil requirement statuspasses
Non-goals
- Running the HTTP server itself (library exposes pure request/response functions)
- LFS transfer adapters beyond
basic(e.g.,lfs-standalone-file, custom transfer agents) - Migration tooling (
git lfs migrate)