thin-fetch 0.1.0

Low-level Git crate to fetch objects with high granularity
Documentation
use crate::object::{Blob, Object};
use crate::{Checkout, Error, HashKind, WithError as _, bail, error};

use super::Repo;

impl Repo {
    #[must_use]
    pub fn get_hash_kind(&self) -> HashKind {
        self.hash_kind
    }

    #[must_use]
    pub fn get_blob(&self, oid: &str) -> Option<&Blob> {
        self.object_cache.get(oid).and_then(|a| match a {
            Object::Blob(blob) => Some(blob),
            _ => None,
        })
    }

    /// Gets linear history of commits between `start` and `end`.
    ///
    /// # Errors
    ///
    /// Returns an error when the history is not linear.
    pub fn get_history_linear<'a>(
        &'a self,
        start: &str,
        end: &str,
    ) -> Result<Vec<Checkout<'a>>, Error> {
        let mut new_head = end.to_owned();
        let mut checkouts = vec![];

        loop {
            let checkout = Checkout::from_pack(&self.object_cache, &new_head)
                .with_err(|| error!("could not create a checkout for commit {new_head}"))?;

            let parents = &checkout.commit.commit.parents;
            if parents.len() > 1 {
                bail!("commit history non-linear");
            }
            checkouts.push(checkout);
            if new_head == start {
                break;
            }
            new_head = parents.first().with_err_msg("no parent")?.to_string();
        }

        Ok(checkouts)
    }
}