rpo 0.1.0-beta.4

Git contribution analysis: commits, file changes, and per-line authorship over time as polars DataFrames
//! libgit2 backend — stubbed for v1. The seam is real so the v2
//! implementation is mechanical: replace each `todo!()` with a git2 call.

use std::path::{Path, PathBuf};

use super::{BlameHunk, Commit, CommitId, FileChange, GitBackend, WalkOptions};
use crate::RpoError;

pub struct Git2Backend {
    _path: PathBuf,
}

impl GitBackend for Git2Backend {
    fn open(path: &Path) -> Result<Self, RpoError> {
        Ok(Self {
            _path: path.to_path_buf(),
        })
    }
    fn head_commit(&self) -> Result<CommitId, RpoError> {
        todo!("backend-git2 not implemented in v1; enable backend-gix")
    }
    fn iter_commits<'a>(
        &'a self,
        _opts: WalkOptions,
    ) -> Box<dyn Iterator<Item = Result<Commit, RpoError>> + 'a> {
        todo!()
    }
    fn diff_tree(
        &self,
        _parent: Option<&CommitId>,
        _child: &CommitId,
    ) -> Result<Vec<FileChange>, RpoError> {
        todo!()
    }
    fn list_tree_paths(&self, _commit: &CommitId) -> Result<Vec<PathBuf>, RpoError> {
        todo!()
    }
    fn blame_file(&self, _commit: &CommitId, _path: &Path) -> Result<Vec<BlameHunk>, RpoError> {
        todo!()
    }
    fn resolve_rev(&self, _rev: &str) -> Result<CommitId, RpoError> {
        todo!()
    }
    fn commit_meta(&self, _id: &CommitId) -> Result<Commit, RpoError> {
        todo!()
    }
    fn tags(&self) -> Result<Vec<(String, CommitId)>, RpoError> {
        todo!()
    }
    fn mailmap_bytes(&self) -> Result<Option<Vec<u8>>, RpoError> {
        todo!()
    }
    fn gitattributes_bytes(&self) -> Result<Option<Vec<u8>>, RpoError> {
        todo!()
    }
    fn thread_handle(&self) -> Result<Self, RpoError> {
        Ok(Self {
            _path: self._path.clone(),
        })
    }
}