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
pub mod downloader;
pub mod pointer;

use crate::auth::SecureString;
use anyhow::Result;
use pointer::{is_lfs_pointer, parse_pointer};
use std::path::Path;
use tracing::{debug, info, warn};
use walkdir::WalkDir;

/// Resolve all LFS pointer files in a repository after acquisition.
pub async fn resolve_lfs_pointers(
    repo_path: &Path,
    repo_url: &str,
    token: Option<&SecureString>,
    _verify_hashes: bool,
) -> Result<usize> {
    let dl = downloader::LfsDownloader::new();
    let mut resolved = 0;

    for entry in WalkDir::new(repo_path)
        .follow_links(false)
        .into_iter()
        .filter_map(|e| e.ok())
    {
        let path = entry.path();
        if !path.is_file() {
            continue;
        }

        // Skip .git directory
        if path.components().any(|c| c.as_os_str() == ".git") {
            continue;
        }

        if let Ok(content) = std::fs::read(path) {
            if is_lfs_pointer(&content) {
                match parse_pointer(&content) {
                    Ok(pointer) => {
                        info!(
                            "Resolving LFS pointer: {} ({} bytes)",
                            path.display(),
                            pointer.size
                        );
                        match dl.download_object(repo_url, &pointer, path, token).await {
                            Ok(()) => {
                                resolved += 1;
                                debug!("Resolved LFS object: {}", path.display());
                            }
                            Err(e) => {
                                warn!("Failed to resolve LFS pointer {}: {}", path.display(), e);
                            }
                        }
                    }
                    Err(e) => {
                        warn!("Invalid LFS pointer {}: {}", path.display(), e);
                    }
                }
            }
        }
    }

    Ok(resolved)
}