weavatrix-git 0.1.1

Dependency-free, evidence-carrying Git repository reader
Documentation

Weavatrix Git

CI crates.io docs.rs

weavatrix-git is a dependency-free, read-only Git storage engine written in safe Rust. Repository-analysis tools get direct, typed evidence without launching git, loading a C library, executing hooks, evaluating filters, or contacting a remote.

The crate is not a second Git client. Its contract is deterministic local intelligence: objects, refs, history, reachability, index state, and changes.

Why a separate crate?

A scanner discovers files. A code graph models relationships. This crate owns version-control evidence. Keeping that boundary independent lets any Rust application reuse Git intelligence without importing a larger product.

Supported contract

Area Support
Layouts worktree, bare, .git indirection, linked worktree commondir
Hashes SHA-1 and SHA-256 object identifiers
Refs loose, symbolic, detached HEAD, packed refs, reflogs
Objects commit, tree, blob, annotated tag
Loose storage bounded zlib/DEFLATE decoded by this crate
Packed storage PACK v2/v3, index v2, OFS_DELTA, REF_DELTA
Object lookup alternates, classic MIDX, caches, shared zero-copy snapshots
Commit acceleration monolithic and split commit-graph chains
Path acceleration changed-path Bloom filters v1/v2
Reachability pack and MIDX EWAH bitmaps with RIDX ordering
Index DIRC v2/v3/v4, auto-refreshing shared snapshots
Queries typed reads, lazy revwalk, history, tracked status, tree diff
Scale-out bounded parallel batches and cross-repository correlation
Extension ordered, thread-safe, read-only custom ODB backends

All public reads are in-process. Library code contains no subprocess fallback. Unsupported data returns a typed error rather than an approximate answer.

Usage

use weavatrix_git::{PathBloom, Repository};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let repository = Repository::open(".")?;
    let head = repository.resolve("HEAD")?;

    for id in repository.revwalk().push_head()?.take(100) {
        println!("{}", id?);
    }

    if repository.commit_maybe_changed_path(head, b"src/lib.rs")?
        == Some(PathBloom::DefinitelyNot)
    {
        println!("the commit definitely did not change src/lib.rs");
    }

    if let Some(objects) = repository.bitmap_reachable(head)? {
        println!("{} reachable objects", objects.len());
    }
    Ok(())
}

Custom stores use the same object contract:

use std::sync::Arc;
use weavatrix_git::{Limits, MemoryObjectBackend, Repository};

let backend = Arc::new(MemoryObjectBackend::default());
let repository =
    Repository::open_with_backends(".", Limits::default(), vec![backend])?;
# Ok::<_, weavatrix_git::GitError>(repository)

For cross-repository analysis, RepositorySet keeps object stores isolated and returns deterministic serial or parallel results:

use weavatrix_git::{HistoryOptions, RepositorySet};

let repositories = RepositorySet::open([
    ("service", "/code/service"),
    ("client", "/code/client"),
])?;
let histories = repositories.histories_parallel(HistoryOptions::default())?;
let shared = repositories.shared_commits(HistoryOptions::default())?;
# Ok::<_, weavatrix_git::GitError>((histories, shared))

The diagnostic CLI uses the library:

weavatrix-git [-C repository] head
weavatrix-git [-C repository] log [revision] [max-count]
weavatrix-git [-C repository] cat <object>
weavatrix-git [-C repository] diff <old-commit> <new-commit>

Architecture

Repository
  +-- refs + reflog
  +-- commit-graph chain + changed-path Bloom
  +-- index -> tracked status
  +-- custom ODB backends
  +-- object directories + alternates
        +-- loose object -> bounded zlib
        +-- MIDX -> pack -> bounded delta chain
        +-- pack/MIDX bitmap -> reachable object IDs

Limits bounds object bytes, cache bytes, delta/ref/tree depth, tree and index entries, reflog/history length, parent count, and bitmap expansion. The crate forbids unsafe Rust.

Correctness

The suite creates real Git repositories and verifies:

  • loose and aggressively packed OFS/REF delta objects;
  • SHA-1 and SHA-256 repositories;
  • bare and linked-worktree layouts;
  • classic MIDX lookup;
  • multi-layer split commit-graphs and changed-path Bloom answers;
  • pack and MIDX bitmap reachability against git rev-list --objects;
  • index v2 and v4, reflog order, revwalk hide/reset, and tracked status;
  • deterministic parallel and cross-repository results;
  • hostile format and configured-limit failures.

Current line coverage is 86.03%. CI runs Rust 1.88 on Linux, Windows, and macOS, Clippy with warnings denied, coverage, audit, docs, and package verification.

Performance

Release measurements on Windows, 2026-07-27:

Exact-parity operation weavatrix-git p50 git.exe p50
6,000-object bitmap reachability 0.431 ms 72.656 ms
one-entry index read 0.033 ms 60.758 ms
clean tracked status 0.186 ms 72.735 ms
cached commit lookup 0.001 ms 65.267 ms
1,000-commit history, reused repository 0.416 ms 68.145 ms

Direct in-process comparison on the same packed 2,000-commit fixture:

Exact-parity operation Weavatrix p50 gix 0.86 p50 git2 0.21 p50
1,000-commit history, warm 0.395 ms 0.425 ms 0.871 ms
1,000-commit history, reopen 3.015 ms 5.285 ms 13.126 ms
1,000 cached object reads 0.080 ms 0.082 ms 7.115 ms
history plus 1,000 raw objects 0.865 ms 1.195 ms 1.554 ms

On a separate 10,000-path index, warm reads measured 0.567/0.508/0.869 ms respectively; reopen measured 4.393/7.361/9.721 ms. The benchmark rotates engine order and proves exact history IDs, raw object bytes, and canonical index paths before timing. See BENCHMARKS.md.

Position among alternatives

Capability weavatrix-git Git CLI gix libgit2
In-process yes no yes yes
Pure safe Rust yes no yes no, C core
Crate dependencies zero n/a many modular crates native library
Object/delta caches yes yes yes yes
MIDX and reachability bitmap reads yes yes yes yes
Split commit-graph and path Bloom reads yes yes yes commit-graph
Custom read-only ODB yes n/a store abstractions yes
Lazy revwalk, reflog, index, tracked status yes yes yes yes
Network and mutation no yes yes yes

The deliberate remaining exclusions are pack index v1, reftable, incremental MIDX chains, split/sparse index extensions, shallow and replace-object semantics, revision-expression grammar, untracked/ignore/filter-aware status, submodule worktree status, network operations, and mutation.

Use Git, gix, or libgit2 for a complete client. Use this crate when bounded local evidence, a small audit surface, deterministic reads, and zero dependencies matter.

License

MIT