diff options
Diffstat (limited to 'apps/servers/octopus/supergit/src/repo.rs')
-rw-r--r-- | apps/servers/octopus/supergit/src/repo.rs | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/apps/servers/octopus/supergit/src/repo.rs b/apps/servers/octopus/supergit/src/repo.rs new file mode 100644 index 000000000000..37991c3a560f --- /dev/null +++ b/apps/servers/octopus/supergit/src/repo.rs @@ -0,0 +1,98 @@ +//! Raw representation wrappers for libgit2 + +use crate::{Branch, BranchCommit}; +use git2::{self, Oid}; +use std::sync::Arc; + +pub type GitResult<T> = Result<T, GitError>; + +/// The hex ID of a commit +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct HashId(String); + +impl HashId { + pub fn to_oid(&self) -> Oid { + self.clone().into() + } + + pub fn to_string(&self) -> String { + self.0.clone() + } +} + +impl From<Oid> for HashId { + fn from(o: Oid) -> Self { + Self(o.to_string()) + } +} + +impl From<HashId> for Oid { + fn from(hid: HashId) -> Self { + Oid::from_str(hid.0.as_str()).expect(&format!( + "Tried turning an invalid HashId variant into an Oid: {:?}", + hid + )) + } +} + +impl<'any> From<&'any HashId> for Oid { + fn from(hid: &'any HashId) -> Self { + Oid::from_str(hid.0.as_str()).expect(&format!( + "Tried turning an invalid HashId variant into an Oid: {:?}", + hid + )) + } +} + +/// An error abstraction for raw git operations +#[derive(Debug)] +pub enum GitError { + AllBad, +} + +impl From<git2::Error> for GitError { + fn from(_: git2::Error) -> Self { + Self::AllBad + } +} + +/// Represents a git repository with lazy data loading +#[derive(Clone)] +pub struct Repository { + inner: Arc<git2::Repository>, +} + +impl Repository { + pub fn open(path: &str) -> GitResult<Self> { + Ok(Self { + inner: Arc::new(git2::Repository::open(path)?), + }) + } + + /// Parse branch data from repository + /// + /// ## Panics + /// + /// If there is an error around getting the name, or head commit. + pub fn branches(&self) -> GitResult<Vec<Branch>> { + Ok(self + .inner + .branches(None)? + .into_iter() + .filter_map(|e| e.ok()) + .map(|(branch, _)| { + let name = branch.name().unwrap().unwrap().into(); + let head = branch.get().peel_to_commit().unwrap().id().into(); + Branch::new(&self.inner, name, head) + }) + .collect()) + } + + /// Get the files touched by a commit + pub fn get_files_for(&self, id: HashId) -> GitResult<Vec<()>> { + let c = self.inner.find_commit(id.into())?; + let tree = c.tree()?; + + todo!() + } +} |