gitmote

gitmote / docs / architecture  ยท  history  ยท  branches

NameModeSize
..
๐Ÿ“„ README.md 1006443639
๐Ÿ“„ alternatives.md 1006441007
๐Ÿ“„ auth.md 1006441808
๐Ÿ“„ ci.md 10064412715
๐Ÿ“„ open-questions.md 1006441474
๐Ÿ“„ request-flows.md 1006444303
๐Ÿ“„ safety.md 1006448571
๐Ÿ“„ storage.md 1006445341
๐Ÿ“„ urls.md 10064411171

gitmote โ€” Architecture

A tiny single-container Go server that speaks git's smart-HTTP protocol, stores repositories in S3-compatible object storage, and keeps its mutable metadata (refs, users, keys, access) in s3lite (SQLite with S3-backed durability). The container itself is disposable โ€” all durable truth lives in S3 + s3lite โ€” so it runs as a single writer that scales to zero: it wakes on a request, serves, and idles back down.

Built for self-hosting a handful of repos, with the door open to invite a few collaborators and to accept commits authored through a web UI. It is explicitly not trying to be GitHub at scale.

Design priorities, in order: safe โ†’ simple โ†’ cheap-to-idle โ†’ fast. Where they conflict, the earlier one wins. Pragmatic beats pure.


The core idea: split git's data by mutability

"Git on S3" is easy except for one thing โ€” atomic ref updates under concurrent writers. Everything else is either immutable or single-writer-safe. So we split git's storage along the axis that decides which store each half wants, and we let real git do the parts that are hard to reimplement:

Data Property Store
Objects & packs Immutable, content-addressed, bulky (~90% of bytes) Plain S3 โ€” synchronous PUT, re-PUT of the same hash is idempotent
Refs, users, keys, ACLs, repo registry, web-edit state Small, mutable, need transactional CAS s3lite โ€” a ref update is one SQL transaction
Everything git actually computes (packing, negotiation, merge-base, โ€ฆ) Hard to reimplement correctly Stock git on ephemeral local disk

The payoff: the single genuinely-hard problem collapses into a one-line SQL compare-and-swap, on a database already trusted in production โ€” plain SQLite (via s3lite) โ€” with no database to operate.


Reading order

The rest of the architecture is split by concern:

Doc What's in it
storage.md The components that make up the container, and where each kind of data lives โ€” S3 object layout and the s3lite schema.
request-flows.md The read path (clone/fetch) and the write path (push, and the compare-and-swap that makes it safe).
safety.md The concurrency & safety model โ€” single writer, the content-before-pointer ordering invariant, and the accepted write-loss window.
auth.md Authentication and transport โ€” smart HTTP + personal access tokens today, SSH deferred.
ci.md CI โ€” running .gitmote/workflows on push: the dispatch seam, the one-runner-three-substrates model, act self-hosted vs. nested, secrets, and the no-in-Job-image-builds limitation.
alternatives.md Approaches considered and rejected or deferred, with the reasoning.
open-questions.md Unsettled decisions โ€” the superset that links into ../notes/.

Speculative, non-committal future directions live in ../evolution/ โ€” read them as ideas, not plans.