summaryrefslogtreecommitdiffstats
path: root/vendor/gix/src/config/cache/access.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix/src/config/cache/access.rs')
-rw-r--r--vendor/gix/src/config/cache/access.rs200
1 files changed, 145 insertions, 55 deletions
diff --git a/vendor/gix/src/config/cache/access.rs b/vendor/gix/src/config/cache/access.rs
index cea56f973..352bc9712 100644
--- a/vendor/gix/src/config/cache/access.rs
+++ b/vendor/gix/src/config/cache/access.rs
@@ -1,16 +1,15 @@
#![allow(clippy::result_large_err)]
use std::{borrow::Cow, path::PathBuf, time::Duration};
-use gix_attributes::Source;
use gix_lock::acquire::Fail;
use crate::{
bstr::BStr,
config,
config::{
- cache::util::{ApplyLeniency, ApplyLeniencyDefault},
- checkout_options,
- tree::{gitoxide, Checkout, Core, Key},
+ boolean,
+ cache::util::{ApplyLeniency, ApplyLeniencyDefaultValue},
+ tree::{Core, Key},
Cache,
},
remote,
@@ -19,7 +18,9 @@ use crate::{
/// Access
impl Cache {
+ #[cfg(feature = "blob-diff")]
pub(crate) fn diff_algorithm(&self) -> Result<gix_diff::blob::Algorithm, config::diff::algorithm::Error> {
+ use crate::config::cache::util::ApplyLeniencyDefault;
use crate::config::diff::algorithm::Error;
self.diff_algorithm
.get_or_try_init(|| {
@@ -69,6 +70,18 @@ impl Cache {
.get_or_try_init(|| remote::url::SchemePermission::from_config(&self.resolved, self.filter_config_section))
}
+ pub(crate) fn may_use_commit_graph(&self) -> Result<bool, config::boolean::Error> {
+ const DEFAULT: bool = true;
+ self.resolved
+ .boolean_by_key("core.commitGraph")
+ .map_or(Ok(DEFAULT), |res| {
+ Core::COMMIT_GRAPH
+ .enrich_error(res)
+ .with_lenient_default_value(self.lenient_config, DEFAULT)
+ })
+ }
+
+ #[cfg(feature = "blob-diff")]
pub(crate) fn diff_renames(
&self,
) -> Result<Option<crate::object::tree::diff::Rewrites>, crate::object::tree::diff::rewrites::Error> {
@@ -100,9 +113,10 @@ impl Cache {
}
/// The path to the user-level excludes file to ignore certain files in the worktree.
+ #[cfg(feature = "excludes")]
pub(crate) fn excludes_file(&self) -> Option<Result<PathBuf, gix_config::path::interpolate::Error>> {
self.trusted_file_path("core", None, Core::EXCLUDES_FILE.name)?
- .map(|p| p.into_owned())
+ .map(std::borrow::Cow::into_owned)
.into()
}
@@ -123,7 +137,7 @@ impl Cache {
let install_dir = crate::path::install_dir().ok();
let home = self.home_dir();
- let ctx = crate::config::cache::interpolate_context(install_dir.as_deref(), home.as_deref());
+ let ctx = config::cache::interpolate_context(install_dir.as_deref(), home.as_deref());
Some(path.interpolate(ctx))
}
@@ -131,80 +145,108 @@ impl Cache {
res.transpose().with_leniency(self.lenient_config)
}
+ pub(crate) fn fs_capabilities(&self) -> Result<gix_fs::Capabilities, boolean::Error> {
+ Ok(gix_fs::Capabilities {
+ precompose_unicode: boolean(self, "core.precomposeUnicode", &Core::PRECOMPOSE_UNICODE, false)?,
+ ignore_case: boolean(self, "core.ignoreCase", &Core::IGNORE_CASE, false)?,
+ executable_bit: boolean(self, "core.fileMode", &Core::FILE_MODE, true)?,
+ symlink: boolean(self, "core.symlinks", &Core::SYMLINKS, true)?,
+ })
+ }
+
+ #[cfg(feature = "index")]
+ pub(crate) fn stat_options(&self) -> Result<gix_index::entry::stat::Options, config::stat_options::Error> {
+ use crate::config::tree::gitoxide;
+ Ok(gix_index::entry::stat::Options {
+ trust_ctime: boolean(
+ self,
+ "core.trustCTime",
+ &Core::TRUST_C_TIME,
+ // For now, on MacOS it's known to not be trust-worthy at least with the Rust STDlib, being 2s off
+ !cfg!(target_os = "macos"),
+ )?,
+ use_nsec: boolean(self, "gitoxide.core.useNsec", &gitoxide::Core::USE_NSEC, false)?,
+ use_stdev: boolean(self, "gitoxide.core.useStdev", &gitoxide::Core::USE_STDEV, false)?,
+ check_stat: self
+ .apply_leniency(
+ self.resolved
+ .string("core", None, "checkStat")
+ .map(|v| Core::CHECK_STAT.try_into_checkstat(v)),
+ )?
+ .unwrap_or(true),
+ })
+ }
+
/// Collect everything needed to checkout files into a worktree.
/// Note that some of the options being returned will be defaulted so safe settings, the caller might have to override them
/// depending on the use-case.
+ #[cfg(feature = "worktree-mutation")]
pub(crate) fn checkout_options(
&self,
- git_dir: &std::path::Path,
- ) -> Result<gix_worktree::checkout::Options, checkout_options::Error> {
- fn boolean(
- me: &Cache,
- full_key: &str,
- key: &'static config::tree::keys::Boolean,
- default: bool,
- ) -> Result<bool, checkout_options::Error> {
- debug_assert_eq!(
- full_key,
- key.logical_name(),
- "BUG: key name and hardcoded name must match"
- );
- Ok(me
- .apply_leniency(me.resolved.boolean_by_key(full_key).map(|v| key.enrich_error(v)))?
- .unwrap_or(default))
- }
-
+ repo: &crate::Repository,
+ attributes_source: gix_worktree::stack::state::attributes::Source,
+ ) -> Result<gix_worktree_state::checkout::Options, config::checkout_options::Error> {
+ use crate::config::tree::gitoxide;
+ let git_dir = repo.git_dir();
let thread_limit = self.apply_leniency(
self.resolved
.integer_filter_by_key("checkout.workers", &mut self.filter_config_section.clone())
- .map(|value| Checkout::WORKERS.try_from_workers(value)),
+ .map(|value| crate::config::tree::Checkout::WORKERS.try_from_workers(value)),
)?;
- let capabilities = gix_fs::Capabilities {
- precompose_unicode: boolean(self, "core.precomposeUnicode", &Core::PRECOMPOSE_UNICODE, false)?,
- ignore_case: boolean(self, "core.ignoreCase", &Core::IGNORE_CASE, false)?,
- executable_bit: boolean(self, "core.fileMode", &Core::FILE_MODE, true)?,
- symlink: boolean(self, "core.symlinks", &Core::SYMLINKS, true)?,
+ let capabilities = self.fs_capabilities()?;
+ let filters = {
+ let collection = Default::default();
+ let mut filters = gix_filter::Pipeline::new(&collection, crate::filter::Pipeline::options(repo)?);
+ if let Ok(mut head) = repo.head() {
+ let ctx = filters.driver_context_mut();
+ ctx.ref_name = head.referent_name().map(|name| name.as_bstr().to_owned());
+ ctx.treeish = head.peel_to_commit_in_place().ok().map(|commit| commit.id);
+ }
+ filters
+ };
+ let filter_process_delay = if boolean(
+ self,
+ "gitoxide.core.filterProcessDelay",
+ &gitoxide::Core::FILTER_PROCESS_DELAY,
+ true,
+ )? {
+ gix_filter::driver::apply::Delay::Allow
+ } else {
+ gix_filter::driver::apply::Delay::Forbid
};
- Ok(gix_worktree::checkout::Options {
+ Ok(gix_worktree_state::checkout::Options {
+ filter_process_delay,
+ filters,
attributes: self
- .assemble_attribute_globals(
- git_dir,
- gix_worktree::cache::state::attributes::Source::IdMappingThenWorktree,
- self.attributes,
- )?
+ .assemble_attribute_globals(git_dir, attributes_source, self.attributes)?
.0,
fs: capabilities,
thread_limit,
destination_is_initially_empty: false,
overwrite_existing: false,
keep_going: false,
- stat_options: gix_index::entry::stat::Options {
- trust_ctime: boolean(self, "core.trustCTime", &Core::TRUST_C_TIME, true)?,
- use_nsec: boolean(self, "gitoxide.core.useNsec", &gitoxide::Core::USE_NSEC, false)?,
- use_stdev: boolean(self, "gitoxide.core.useStdev", &gitoxide::Core::USE_STDEV, false)?,
- check_stat: self
- .apply_leniency(
- self.resolved
- .string("core", None, "checkStat")
- .map(|v| Core::CHECK_STAT.try_into_checkstat(v)),
- )?
- .unwrap_or(true),
- },
+ stat_options: self.stat_options().map_err(|err| match err {
+ config::stat_options::Error::ConfigCheckStat(err) => {
+ config::checkout_options::Error::ConfigCheckStat(err)
+ }
+ config::stat_options::Error::ConfigBoolean(err) => config::checkout_options::Error::ConfigBoolean(err),
+ })?,
})
}
+ #[cfg(feature = "excludes")]
pub(crate) fn assemble_exclude_globals(
&self,
git_dir: &std::path::Path,
overrides: Option<gix_ignore::Search>,
- source: gix_worktree::cache::state::ignore::Source,
+ source: gix_worktree::stack::state::ignore::Source,
buf: &mut Vec<u8>,
- ) -> Result<gix_worktree::cache::state::Ignore, config::exclude_stack::Error> {
+ ) -> Result<gix_worktree::stack::state::Ignore, config::exclude_stack::Error> {
let excludes_file = match self.excludes_file().transpose()? {
Some(user_path) => Some(user_path),
None => self.xdg_config_path("ignore")?,
};
- Ok(gix_worktree::cache::state::Ignore::new(
+ Ok(gix_worktree::stack::state::Ignore::new(
overrides.unwrap_or_default(),
gix_ignore::Search::from_git_dir(git_dir, excludes_file, buf)?,
None,
@@ -212,12 +254,14 @@ impl Cache {
))
}
// TODO: at least one test, maybe related to core.attributesFile configuration.
+ #[cfg(feature = "attributes")]
pub(crate) fn assemble_attribute_globals(
&self,
git_dir: &std::path::Path,
- source: gix_worktree::cache::state::attributes::Source,
+ source: gix_worktree::stack::state::attributes::Source,
attributes: crate::open::permissions::Attributes,
- ) -> Result<(gix_worktree::cache::state::Attributes, Vec<u8>), config::attribute_stack::Error> {
+ ) -> Result<(gix_worktree::stack::state::Attributes, Vec<u8>), config::attribute_stack::Error> {
+ use gix_attributes::Source;
let configured_or_user_attributes = match self
.trusted_file_path("core", None, Core::ATTRIBUTES_FILE.name)
.transpose()?
@@ -243,15 +287,45 @@ impl Cache {
let info_attributes_path = git_dir.join("info").join("attributes");
let mut buf = Vec::new();
let mut collection = gix_attributes::search::MetadataCollection::default();
- let res = gix_worktree::cache::state::Attributes::new(
+ let state = gix_worktree::stack::state::Attributes::new(
gix_attributes::Search::new_globals(attribute_files, &mut buf, &mut collection)?,
Some(info_attributes_path),
source,
collection,
);
- Ok((res, buf))
+ Ok((state, buf))
}
+ #[cfg(feature = "attributes")]
+ pub(crate) fn pathspec_defaults(
+ &self,
+ ) -> Result<gix_pathspec::Defaults, gix_pathspec::defaults::from_environment::Error> {
+ use crate::config::tree::gitoxide;
+ let res = gix_pathspec::Defaults::from_environment(&mut |name| {
+ let key = [
+ &gitoxide::Pathspec::ICASE,
+ &gitoxide::Pathspec::GLOB,
+ &gitoxide::Pathspec::NOGLOB,
+ &gitoxide::Pathspec::LITERAL,
+ ]
+ .iter()
+ .find_map(|key| (key.environment_override().expect("set") == name).then_some(key))
+ .expect("we must know all possible input variable names");
+
+ let val = self
+ .resolved
+ .string("gitoxide", Some("pathspec".into()), key.name())
+ .map(gix_path::from_bstr)?;
+ Some(val.into_owned().into())
+ });
+ if res.is_err() && self.lenient_config {
+ Ok(gix_pathspec::Defaults::default())
+ } else {
+ res
+ }
+ }
+
+ #[cfg(any(feature = "attributes", feature = "excludes"))]
pub(crate) fn xdg_config_path(
&self,
resource_file_name: &str,
@@ -284,3 +358,19 @@ impl Cache {
gix_path::env::home_dir().and_then(|path| self.environment.home.check_opt(path))
}
}
+
+fn boolean(
+ me: &Cache,
+ full_key: &str,
+ key: &'static config::tree::keys::Boolean,
+ default: bool,
+) -> Result<bool, boolean::Error> {
+ debug_assert_eq!(
+ full_key,
+ key.logical_name(),
+ "BUG: key name and hardcoded name must match"
+ );
+ Ok(me
+ .apply_leniency(me.resolved.boolean_by_key(full_key).map(|v| key.enrich_error(v)))?
+ .unwrap_or(default))
+}