git-to-graph is a Go CLI that turns your repository history into a temporal code knowledge graph and loads it into NornicDB.
It replays commits, extracts code facts (files, symbols, relationships), versions those facts over time, and writes both:
- ledger artifacts (
.jsonl) - graph load artifacts (
.cypher) - optional direct inserts into NornicDB
Use this when you want a queryable graph of your codebase with commit-aware evolution:
- Track how symbols and relationships change over time
- Ask commit-to-commit questions (
:CHANGED,:IMPACTS,valid_from/valid_to) - Build agent/context tooling on top of a persistent knowledge graph
go mod tidy
go build -o g2g ./cmd/g2gDefaults are already local-friendly:
--db-uri bolt://localhost:7687--db-user admin--db-password password
So this is enough:
./g2g index .Equivalent explicit command:
./g2g index . \
--parser-backend auto \
--db-uri bolt://localhost:7687 \
--db-user admin \
--db-password passwordFor each run, g2g:
- Scans commit history
- Rebuilds code state by commit
- Writes temporal ledger artifacts
- Exports Cypher statements
- Applies to NornicDB (unless disabled)
During apply, g2g auto-generates and runs g2g-bootstrap.cypher first to create indexes/constraints with IF NOT EXISTS.
index: build ledger, export graph artifacts, optionally apply to DBasof: reconstruct graph snapshot from ledger at a timestamp
./g2g index ../g2g index /absolute/path/to/repoPass an empty DB URI:
./g2g index . --db-uri "" --out ./.git2graph./g2g index . \
--db-uri http://localhost:7474/graphql \
--db-user admin \
--db-password password./g2g index . \
--bootstrap-cypher /absolute/path/to/bootstrap.cypherYour bootstrap file runs after the auto-bootstrap and before data inserts.
--parser-backend:
auto(default): prefer SCIP when available, otherwise Tree-sitterscip: prefer SCIP, fallback to Tree-sittertree-sitter: force Tree-sitterregex: minimal fallback
--out defaults to ./.git2graph (or a temp dir when direct DB apply is enabled).
Artifacts:
ledger_versions.jsonlmutation_events.jsonlnornic_versions.cyphernornic_events.cypher
./g2g asof \
--ledger ./.git2graph/ledger_versions.jsonl \
--time 2025-01-01T00:00:00ZEnvironment variables:
G2G_DB_BATCH_SIZE(default25)G2G_DB_STATEMENT_TIMEOUT_SEC(default120)
Example:
G2G_DB_BATCH_SIZE=100 G2G_DB_STATEMENT_TIMEOUT_SEC=180 ./g2g index .Run these in Nornic query UI:
MATCH (cs:CodeState) RETURN count(*) AS c;MATCH (cc:CodeChange) RETURN count(*) AS c;MATCH (c:Commit) RETURN count(*) AS c;MATCH (:CodeKey)-[:HAS_STATE]->(:CodeState) RETURN count(*) AS c;g2g uses Nornic GraphQL executeCypher, so you can run ad-hoc graph queries the same way.
Base endpoint (default local):
http://localhost:7474/graphql
Example request:
curl -s -u admin:password \
-H 'Content-Type: application/json' \
http://localhost:7474/graphql \
--data-binary @- <<'JSON'
{"query":"mutation ExecuteCypher($input: CypherInput!) { executeCypher(input: $input) { rowCount } }","variables":{"input":{"statement":"MATCH (c:Commit) RETURN c.hash LIMIT 10"}}}
JSONThese queries were validated against local Nornic using the curl pattern above.
Find commit and change context by transaction id:
MATCH (c:Commit)
WHERE c.tx_id = '005e98bb-894e-4d71-99f6-2810fec1ddcc'
RETURN c.hash, c.timestamp, c.actor
LIMIT 5Commit to changed versions:
MATCH (c:Commit)-[:CHANGED]->(cs:CodeState)
RETURN c.hash, cs.state_id
LIMIT 10Mutation events to affected versions:
MATCH (cc:CodeChange)-[:IMPACTS]->(cs:CodeState)
RETURN cc.change_id, cs.state_id
LIMIT 10Fact keys to versions:
MATCH (ck:CodeKey)-[:HAS_STATE]->(cs:CodeState)
RETURN ck.relation_type, cs.state_id
LIMIT 10Explore call facts:
MATCH (cs:CodeState)
WHERE cs.code_key CONTAINS 'repo_fact|calls|'
RETURN cs.code_key, cs.commit_hash
LIMIT 10Explore import facts:
MATCH (cs:CodeState)
WHERE cs.code_key CONTAINS 'repo_fact|import|'
RETURN cs.code_key, cs.commit_hash
LIMIT 10CodeState(state_id)is indexed by default (not unique-constrained) to avoid startup failures on pre-existing duplicate historical rows.- For strict uniqueness, clean duplicates first, then add your own unique constraint.