The space where version control meets databases is well-trodden. But each neighbour occupies a different point than geschichte, and the specific intersection geschichte targets — real Git that is simultaneously a queryable Datalog database — came back empty from a fairly thorough survey. This note maps the landscape and places geschichte in it.
The recurring distinction: geschichte stores real Git — genuine objects, packs, refs, and the wire protocol, interoperable with native Git — but persists them inside Datahike, so the Git object graph itself is queryable with Datalog and graph algorithms. It is at once (a) a real Git implementation and (b) a queryable database. Each category below is contrasted against that dual identity.
libgit2's pluggable object-database backend (git_odb_backend, with a parallel
git_refdb_backend) is the mechanism that lets real Git objects live on a
foreign store, exposed through bindings like
pygit2. Implementations:
push/clone work against the DB, and it adds SQL views that parse
commits/trees into rows. Active proof-of-concept (2026).DfsObjDatabase — the
production way to put real objects (as pack files) into non-filesystem
stores; the foundation under Gerrit and Google's Git infrastructure.Distinction: these hold real Git objects but as a SHA-keyed blob store — no rich query surface (gitgres and JGit are partial exceptions, offering SQL views / pack storage, not a graph query over the object DAG). geschichte adds the query layer these lack. (Note: production forges — GitHub Spokes/DGit, GitLab Gitaly — keep objects as plain pack files on disk; their SQL DBs hold only cluster metadata.)
fossil sql). The closest
philosophical cousin — a DB-native VCS you can query with SQL — but it is
not Git (no object/pack/wire interop) and queries its own derived schema,
not the Git graph.commit/branch/merge/diff). Storage
is prolly-tree-based (from Noms), not real Git objects. Very active.irmin-git backend writes a format real
Git can inspect — the partial real-Git exception here — but it is a storage
layer for irmin's own data model, with no query language.Distinction: these reimplement Git-like semantics over bespoke storage, with SQL or WOQL over their own data model and no real-Git interop.
commits, files, blame). Stalled
(last beta 2023).duck_tails
— Git-aware SQL; active.Distinction: these are a transient lens held up to unchanged on-disk Git — the query engine is never the system of record. You cannot transactionally write, index, branch, or time-travel through the query layer. A Datalog engine over local Git was found nowhere.
Git is itself a content-addressed Merkle DAG. Adjacent machinery: IPFS/IPLD (a general Merkle-DAG data model; its go-ipld-git codec even represents real Git objects as IPLD nodes, but purely as a non-queryable traversal codec), and prolly trees (content-defined-chunked Merkle B-trees giving history independence and diff-cost proportional to the change — the basis of Dolt and ex-Noms). Complementary techniques geschichte could borrow, not a VCS.
geschichte is the only surveyed system that is simultaneously a faithful real Git implementation and a first-class queryable database, where the Git object graph is the primary store, expressed as datoms and interrogable with Datalog and graph algorithms. The individual ingredients — pluggable ODBs, DB-native VCS, Git-for-data semantics, prolly-tree sharing, content-addressed DAGs — are all mature prior art; geschichte's contribution is the specific composition: real Git rehoused inside an immutable Datalog database rather than mirrored, approximated, or queried read-only.
Caveats: "stalled"/"dead" labels are inferred from release cadence and archival
state, not formal shutdown notices. irmin-git and go-ipld-git are the
partial real-Git exceptions noted above. Project statuses are as of early 2026.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |