diff options
Diffstat (limited to 'vendor/gix/src/repository/attributes.rs')
-rw-r--r-- | vendor/gix/src/repository/attributes.rs | 119 |
1 files changed, 104 insertions, 15 deletions
diff --git a/vendor/gix/src/repository/attributes.rs b/vendor/gix/src/repository/attributes.rs index 252529761..7f747f7fd 100644 --- a/vendor/gix/src/repository/attributes.rs +++ b/vendor/gix/src/repository/attributes.rs @@ -1,5 +1,15 @@ //! exclude information -use crate::Repository; +use crate::{config, AttributeStack, Repository}; + +/// The error returned by [`Repository::attributes()`]. +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum Error { + #[error(transparent)] + ConfigureAttributes(#[from] config::attribute_stack::Error), + #[error(transparent)] + ConfigureExcludes(#[from] config::exclude_stack::Error), +} impl Repository { /// Configure a file-system cache for accessing git attributes *and* excludes on a per-path basis. @@ -14,15 +24,14 @@ impl Repository { /// /// * `$XDG_CONFIG_HOME/…/ignore|attributes` if `core.excludesFile|attributesFile` is *not* set, otherwise use the configured file. /// * `$GIT_DIR/info/exclude|attributes` if present. - // TODO: test, provide higher-level custom Cache wrapper that is much easier to use and doesn't panic when accessing entries - // by non-relative path. + #[cfg(feature = "attributes")] pub fn attributes( &self, index: &gix_index::State, - attributes_source: gix_worktree::cache::state::attributes::Source, - ignore_source: gix_worktree::cache::state::ignore::Source, + attributes_source: gix_worktree::stack::state::attributes::Source, + ignore_source: gix_worktree::stack::state::ignore::Source, exclude_overrides: Option<gix_ignore::Search>, - ) -> Result<gix_worktree::Cache, crate::attributes::Error> { + ) -> Result<AttributeStack<'_>, Error> { let case = if self.config.ignore_case { gix_glob::pattern::Case::Fold } else { @@ -36,15 +45,95 @@ impl Repository { let ignore = self.config .assemble_exclude_globals(self.git_dir(), exclude_overrides, ignore_source, &mut buf)?; - let state = gix_worktree::cache::State::AttributesAndIgnoreStack { attributes, ignore }; - let attribute_list = state.id_mappings_from_index(index, index.path_backing(), ignore_source, case); - Ok(gix_worktree::Cache::new( - // this is alright as we don't cause mutation of that directory, it's virtual. - self.work_dir().unwrap_or(self.git_dir()), - state, - case, - buf, - attribute_list, + let state = gix_worktree::stack::State::AttributesAndIgnoreStack { attributes, ignore }; + let attribute_list = state.id_mappings_from_index(index, index.path_backing(), case); + Ok(AttributeStack::new( + gix_worktree::Stack::new( + // this is alright as we don't cause mutation of that directory, it's virtual. + self.work_dir().unwrap_or(self.git_dir()), + state, + case, + buf, + attribute_list, + ), + self, + )) + } + + /// Like [attributes()][Self::attributes()], but without access to exclude/ignore information. + #[cfg(feature = "attributes")] + pub fn attributes_only( + &self, + index: &gix_index::State, + attributes_source: gix_worktree::stack::state::attributes::Source, + ) -> Result<AttributeStack<'_>, config::attribute_stack::Error> { + let case = if self.config.ignore_case { + gix_glob::pattern::Case::Fold + } else { + gix_glob::pattern::Case::Sensitive + }; + let (attributes, buf) = self.config.assemble_attribute_globals( + self.git_dir(), + attributes_source, + self.options.permissions.attributes, + )?; + let state = gix_worktree::stack::State::AttributesStack(attributes); + let attribute_list = state.id_mappings_from_index(index, index.path_backing(), case); + Ok(AttributeStack::new( + gix_worktree::Stack::new( + // this is alright as we don't cause mutation of that directory, it's virtual. + self.work_dir().unwrap_or(self.git_dir()), + state, + case, + buf, + attribute_list, + ), + self, + )) + } + + /// Configure a file-system cache checking if files below the repository are excluded, reading `.gitignore` files from + /// the specified `source`. + /// + /// Note that no worktree is required for this to work, even though access to in-tree `.gitignore` files would require + /// a non-empty `index` that represents a tree with `.gitignore` files. + /// + /// This takes into consideration all the usual repository configuration, namely: + /// + /// * `$XDG_CONFIG_HOME/…/ignore` if `core.excludesFile` is *not* set, otherwise use the configured file. + /// * `$GIT_DIR/info/exclude` if present. + /// + /// When only excludes are desired, this is the most efficient way to obtain them. Otherwise use + /// [`Repository::attributes()`] for accessing both attributes and excludes. + // TODO: test + #[cfg(feature = "excludes")] + pub fn excludes( + &self, + index: &gix_index::State, + overrides: Option<gix_ignore::Search>, + source: gix_worktree::stack::state::ignore::Source, + ) -> Result<AttributeStack<'_>, config::exclude_stack::Error> { + let case = if self.config.ignore_case { + gix_glob::pattern::Case::Fold + } else { + gix_glob::pattern::Case::Sensitive + }; + let mut buf = Vec::with_capacity(512); + let ignore = self + .config + .assemble_exclude_globals(self.git_dir(), overrides, source, &mut buf)?; + let state = gix_worktree::stack::State::IgnoreStack(ignore); + let attribute_list = state.id_mappings_from_index(index, index.path_backing(), case); + Ok(AttributeStack::new( + gix_worktree::Stack::new( + // this is alright as we don't cause mutation of that directory, it's virtual. + self.work_dir().unwrap_or(self.git_dir()), + state, + case, + buf, + attribute_list, + ), + self, )) } } |