securegit 0.8.5

Zero-trust git replacement with 12 built-in security scanners, LLM redteam bridge, universal undo, durable backups, and a 50-tool MCP server
Documentation
use anyhow::Result;
use git2::Repository;
use serde::de::DeserializeOwned;
use serde::Serialize;

/// Store a JSON-serializable value as a blob under a custom ref.
pub fn write_json_ref<T: Serialize>(repo: &Repository, ref_name: &str, value: &T) -> Result<()> {
    let json = serde_json::to_vec_pretty(value)?;
    let blob_oid = repo.blob(&json)?;
    repo.reference(ref_name, blob_oid, true, "securegit metadata")?;
    Ok(())
}

/// Read a JSON value from a custom ref.
pub fn read_json_ref<T: DeserializeOwned>(repo: &Repository, ref_name: &str) -> Result<Option<T>> {
    match repo.find_reference(ref_name) {
        Ok(reference) => {
            let blob = reference.peel_to_blob()?;
            let value: T = serde_json::from_slice(blob.content())?;
            Ok(Some(value))
        }
        Err(_) => Ok(None),
    }
}

/// List all ref names matching a glob prefix.
pub fn list_refs_with_prefix(repo: &Repository, prefix: &str) -> Result<Vec<String>> {
    let mut refs = Vec::new();
    let pattern = format!("{}*", prefix);
    for r in repo.references_glob(&pattern)?.flatten() {
        if let Some(name) = r.name() {
            refs.push(name.to_string());
        }
    }
    Ok(refs)
}

/// Delete a custom ref.
pub fn delete_ref(repo: &Repository, ref_name: &str) -> Result<()> {
    if let Ok(mut reference) = repo.find_reference(ref_name) {
        reference.delete()?;
    }
    Ok(())
}