1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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))
}
}