gix 0.90.0

Interact with git repositories just like git would
Documentation
use gix_error::ResultExt;

use crate::{Repository, Result, filter, worktree::IndexPersistedOrInMemory};

impl Repository {
    /// Configure a pipeline for converting byte buffers to the worktree representation, and byte streams to the git-internal
    /// representation. Also return the index that was used when initializing the pipeline as it may be useful when calling
    /// [convert_to_git()](filter::Pipeline::convert_to_git()).
    /// Bare repositories will either use `HEAD^{tree}` for accessing all relevant worktree files or the given `tree_if_bare`.
    ///
    /// Note that this is considered a primitive as it operates on data directly and will not have permanent effects.
    /// We also return the index that was used to configure the attributes cache (for accessing `.gitattributes`), which can be reused
    /// after it was possibly created from a tree, an expensive operation.
    ///
    /// ### Performance
    ///
    /// Note that when in a repository with worktree, files in the worktree will be read with priority, which causes at least a stat
    /// each time the directory is changed. This can be expensive if access isn't in sorted order, which would cause more then necessary
    /// stats: one per directory.
    pub fn filter_pipeline(
        &self,
        tree_if_bare: Option<gix_hash::ObjectId>,
    ) -> Result<(filter::Pipeline<'_>, IndexPersistedOrInMemory)> {
        let (cache, index) = if self.is_bare() {
            let tree = tree_if_bare.map_or_else(
                || -> Result<_> {
                    let commit = self
                        .head_commit()
                        .or_raise(|| gix_error::message("Could not obtain head commit of bare repository"))?;
                    Ok(commit.tree_id()?.detach())
                },
                Ok,
            )?;
            let index = self.index_from_tree(&tree)?;
            let cache = self.attributes_only(&index, gix_worktree::stack::state::attributes::Source::IdMapping)?;
            (cache, IndexPersistedOrInMemory::InMemory(index))
        } else {
            let index = self.index_or_empty()?;
            let cache = self.attributes_only(
                &index,
                gix_worktree::stack::state::attributes::Source::WorktreeThenIdMapping,
            )?;
            (cache, IndexPersistedOrInMemory::Persisted(index))
        };
        Ok((filter::Pipeline::new(self, cache.detach())?, index))
    }
}