diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/gix/src/config | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix/src/config')
-rw-r--r-- | vendor/gix/src/config/cache/access.rs | 121 | ||||
-rw-r--r-- | vendor/gix/src/config/cache/init.rs | 68 | ||||
-rw-r--r-- | vendor/gix/src/config/cache/util.rs | 12 | ||||
-rw-r--r-- | vendor/gix/src/config/mod.rs | 88 | ||||
-rw-r--r-- | vendor/gix/src/config/snapshot/access.rs | 13 | ||||
-rw-r--r-- | vendor/gix/src/config/snapshot/credential_helpers.rs | 24 | ||||
-rw-r--r-- | vendor/gix/src/config/tree/sections/core.rs | 6 | ||||
-rw-r--r-- | vendor/gix/src/config/tree/sections/diff.rs | 74 | ||||
-rw-r--r-- | vendor/gix/src/config/tree/sections/fetch.rs | 3 | ||||
-rw-r--r-- | vendor/gix/src/config/tree/sections/gitoxide.rs | 90 | ||||
-rw-r--r-- | vendor/gix/src/config/tree/sections/http.rs | 4 |
11 files changed, 462 insertions, 41 deletions
diff --git a/vendor/gix/src/config/cache/access.rs b/vendor/gix/src/config/cache/access.rs index 3e763c028..464a0bf4d 100644 --- a/vendor/gix/src/config/cache/access.rs +++ b/vendor/gix/src/config/cache/access.rs @@ -20,8 +20,7 @@ use crate::{ 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; + use crate::config::{cache::util::ApplyLeniencyDefault, diff::algorithm::Error}; self.diff_algorithm .get_or_try_init(|| { let name = self @@ -39,6 +38,97 @@ impl Cache { .copied() } + #[cfg(feature = "blob-diff")] + pub(crate) fn diff_drivers(&self) -> Result<Vec<gix_diff::blob::Driver>, config::diff::drivers::Error> { + use crate::config::cache::util::ApplyLeniencyDefault; + let mut out = Vec::<gix_diff::blob::Driver>::new(); + for section in self + .resolved + .sections_by_name("diff") + .into_iter() + .flatten() + .filter(|s| (self.filter_config_section)(s.meta())) + { + let Some(name) = section.header().subsection_name().filter(|n| !n.is_empty()) else { + continue; + }; + + let driver = match out.iter_mut().find(|d| d.name == name) { + Some(existing) => existing, + None => { + out.push(gix_diff::blob::Driver { + name: name.into(), + ..Default::default() + }); + out.last_mut().expect("just pushed") + } + }; + + if let Some(binary) = section.value_implicit("binary") { + driver.is_binary = config::tree::Diff::DRIVER_BINARY + .try_into_binary(binary) + .with_leniency(self.lenient_config) + .map_err(|err| config::diff::drivers::Error { + name: driver.name.clone(), + attribute: "binary", + source: Box::new(err), + })?; + } + if let Some(command) = section.value(config::tree::Diff::DRIVER_COMMAND.name) { + driver.command = command.into_owned().into(); + } + if let Some(textconv) = section.value(config::tree::Diff::DRIVER_TEXTCONV.name) { + driver.binary_to_text_command = textconv.into_owned().into(); + } + if let Some(algorithm) = section.value("algorithm") { + driver.algorithm = config::tree::Diff::DRIVER_ALGORITHM + .try_into_algorithm(algorithm) + .or_else(|err| match err { + config::diff::algorithm::Error::Unimplemented { .. } if self.lenient_config => { + Ok(gix_diff::blob::Algorithm::Histogram) + } + err => Err(err), + }) + .with_lenient_default(self.lenient_config) + .map_err(|err| config::diff::drivers::Error { + name: driver.name.clone(), + attribute: "algorithm", + source: Box::new(err), + })? + .into(); + } + } + Ok(out) + } + + #[cfg(feature = "blob-diff")] + pub(crate) fn diff_pipeline_options( + &self, + ) -> Result<gix_diff::blob::pipeline::Options, config::diff::pipeline_options::Error> { + Ok(gix_diff::blob::pipeline::Options { + large_file_threshold_bytes: self.big_file_threshold()?, + fs: self.fs_capabilities()?, + }) + } + + #[cfg(feature = "blob-diff")] + pub(crate) fn diff_renames(&self) -> Result<Option<crate::diff::Rewrites>, crate::diff::new_rewrites::Error> { + self.diff_renames + .get_or_try_init(|| crate::diff::new_rewrites(&self.resolved, self.lenient_config)) + .copied() + } + + #[cfg(feature = "blob-diff")] + pub(crate) fn big_file_threshold(&self) -> Result<u64, config::unsigned_integer::Error> { + Ok(self + .resolved + .integer_by_key("core.bigFileThreshold") + .map(|number| Core::BIG_FILE_THRESHOLD.try_into_u64(number)) + .transpose() + .with_leniency(self.lenient_config)? + .unwrap_or(512 * 1024 * 1024)) + } + /// Returns a user agent for use with servers. #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] pub(crate) fn user_agent_tuple(&self) -> (&'static str, Option<Cow<'static, str>>) { @@ -54,6 +144,18 @@ impl Cache { ("agent", Some(gix_protocol::agent(agent).into())) } + /// Return `true` if packet-tracing is enabled. Lenient and defaults to `false`. + #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] + pub(crate) fn trace_packet(&self) -> bool { + use config::tree::Gitoxide; + + use crate::config::tree::Section; + self.resolved + .boolean(Gitoxide.name(), None, Gitoxide::TRACE_PACKET.name()) + .and_then(Result::ok) + .unwrap_or_default() + } + pub(crate) fn personas(&self) -> &identity::Personas { self.personas .get_or_init(|| identity::Personas::from_config_and_env(&self.resolved)) @@ -81,17 +183,6 @@ impl Cache { }) } - #[cfg(feature = "blob-diff")] - pub(crate) fn diff_renames( - &self, - ) -> Result<Option<crate::object::tree::diff::Rewrites>, crate::object::tree::diff::rewrites::Error> { - self.diff_renames - .get_or_try_init(|| { - crate::object::tree::diff::Rewrites::try_from_config(&self.resolved, self.lenient_config) - }) - .copied() - } - /// Returns (file-timeout, pack-refs timeout) pub(crate) fn lock_timeout( &self, @@ -189,8 +280,8 @@ impl Cache { )?; let capabilities = self.fs_capabilities()?; let filters = { - let collection = Default::default(); - let mut filters = gix_filter::Pipeline::new(&collection, crate::filter::Pipeline::options(repo)?); + let mut filters = + gix_filter::Pipeline::new(repo.command_context()?, 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()); diff --git a/vendor/gix/src/config/cache/init.rs b/vendor/gix/src/config/cache/init.rs index 3c482b154..faf3cc8de 100644 --- a/vendor/gix/src/config/cache/init.rs +++ b/vendor/gix/src/config/cache/init.rs @@ -9,7 +9,7 @@ use crate::{ config, config::{ cache::util::ApplyLeniency, - tree::{gitoxide, Core, Http}, + tree::{gitoxide, Core, Gitoxide, Http}, Cache, }, open, @@ -143,6 +143,7 @@ impl Cache { use util::config_bool; let reflog = util::query_refupdates(&config, lenient_config)?; + let refs_namespace = util::query_refs_namespace(&config, lenient_config)?; let ignore_case = config_bool(&config, &Core::IGNORE_CASE, "core.ignoreCase", false, lenient_config)?; let use_multi_pack_index = config_bool( &config, @@ -166,6 +167,7 @@ impl Cache { pack_cache_bytes, object_cache_bytes, reflog, + refs_namespace, is_bare, ignore_case, hex_len, @@ -222,10 +224,12 @@ impl Cache { self.object_kind_hint = object_kind_hint; } let reflog = util::query_refupdates(config, self.lenient_config)?; + let refs_namespace = util::query_refs_namespace(config, self.lenient_config)?; self.hex_len = hex_len; self.ignore_case = ignore_case; self.reflog = reflog; + self.refs_namespace = refs_namespace; self.user_agent = Default::default(); self.personas = Default::default(); @@ -298,6 +302,7 @@ impl crate::Repository { fn apply_changed_values(&mut self) { self.refs.write_reflog = util::reflog_or_default(self.config.reflog, self.work_dir().is_some()); + self.refs.namespace = self.config.refs_namespace.clone(); } } @@ -339,6 +344,15 @@ fn apply_environment_overrides( ), ( "gitoxide", + None, + git_prefix, + &[{ + let key = &Gitoxide::TRACE_PACKET; + (env(key), key.name) + }], + ), + ( + "gitoxide", Some(Cow::Borrowed("https".into())), http_transport, &[ @@ -377,6 +391,30 @@ fn apply_environment_overrides( ), ( "gitoxide", + Some(Cow::Borrowed("http".into())), + git_prefix, + &[{ + let key = &gitoxide::Http::SSL_NO_VERIFY; + (env(key), key.name) + }], + ), + ( + "gitoxide", + Some(Cow::Borrowed("credentials".into())), + git_prefix, + &[ + { + let key = &gitoxide::Credentials::TERMINAL_PROMPT; + (env(key), key.name) + }, + { + let key = &gitoxide::Credentials::HELPER_STDERR; + (env(key), key.name) + }, + ], + ), + ( + "gitoxide", Some(Cow::Borrowed("committer".into())), identity, &[ @@ -394,10 +432,20 @@ fn apply_environment_overrides( "gitoxide", Some(Cow::Borrowed("core".into())), git_prefix, - &[{ - let key = &gitoxide::Core::SHALLOW_FILE; - (env(key), key.name) - }], + &[ + { + let key = &gitoxide::Core::SHALLOW_FILE; + (env(key), key.name) + }, + { + let key = &gitoxide::Core::REFS_NAMESPACE; + (env(key), key.name) + }, + { + let key = &gitoxide::Core::EXTERNAL_COMMAND_STDERR; + (env(key), key.name) + }, + ], ), ( "gitoxide", @@ -500,6 +548,16 @@ fn apply_environment_overrides( (env(key), key.name) }], ), + #[cfg(feature = "blob-diff")] + ( + "diff", + None, + git_prefix, + &[{ + let key = &config::tree::Diff::EXTERNAL; + (env(key), key.name) + }], + ), ] { let mut section = env_override .new_section(section_name, subsection_name) diff --git a/vendor/gix/src/config/cache/util.rs b/vendor/gix/src/config/cache/util.rs index 4032b2cb1..4c1d6c693 100644 --- a/vendor/gix/src/config/cache/util.rs +++ b/vendor/gix/src/config/cache/util.rs @@ -55,6 +55,18 @@ pub(crate) fn query_refupdates( .map_err(Into::into) } +pub(crate) fn query_refs_namespace( + config: &gix_config::File<'static>, + lenient_config: bool, +) -> Result<Option<gix_ref::Namespace>, config::refs_namespace::Error> { + let key = "gitoxide.core.refsNamespace"; + config + .string_by_key(key) + .map(|ns| gitoxide::Core::REFS_NAMESPACE.try_into_refs_namespace(ns)) + .transpose() + .with_leniency(lenient_config) +} + pub(crate) fn reflog_or_default( config_reflog: Option<gix_ref::store::WriteReflog>, has_worktree: bool, diff --git a/vendor/gix/src/config/mod.rs b/vendor/gix/src/config/mod.rs index 102c7a482..301e19ba2 100644 --- a/vendor/gix/src/config/mod.rs +++ b/vendor/gix/src/config/mod.rs @@ -76,6 +76,8 @@ pub enum Error { ConfigUnsigned(#[from] unsigned_integer::Error), #[error(transparent)] ConfigTypedString(#[from] key::GenericErrorWithValue), + #[error(transparent)] + RefsNamespace(#[from] refs_namespace::Error), #[error("Cannot handle objects formatted as {:?}", .name)] UnsupportedObjectFormat { name: BString }, #[error(transparent)] @@ -91,8 +93,11 @@ pub enum Error { ResolveIncludes(#[from] gix_config::file::includes::Error), #[error(transparent)] FromEnv(#[from] gix_config::file::init::from_env::Error), - #[error(transparent)] - PathInterpolation(#[from] gix_config::path::interpolate::Error), + #[error("The path {path:?} at the 'core.worktree' configuration could not be interpolated")] + PathInterpolation { + path: BString, + source: gix_config::path::interpolate::Error, + }, #[error("{source:?} configuration overrides at open or init time could not be applied.")] ConfigOverrides { #[source] @@ -117,6 +122,36 @@ pub mod diff { Unimplemented { name: BString }, } } + + /// + pub mod pipeline_options { + /// The error produced when obtaining options needed to fill in [gix_diff::blob::pipeline::Options]. + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + pub enum Error { + #[error(transparent)] + FilesystemCapabilities(#[from] crate::config::boolean::Error), + #[error(transparent)] + BigFileThreshold(#[from] crate::config::unsigned_integer::Error), + } + } + + /// + pub mod drivers { + use crate::bstr::BString; + + /// The error produced when obtaining a list of [Drivers](gix_diff::blob::Driver). + #[derive(Debug, thiserror::Error)] + #[error("Failed to parse value of 'diff.{name}.{attribute}'")] + pub struct Error { + /// The name fo the driver. + pub name: BString, + /// The name of the attribute we tried to parse. + pub attribute: &'static str, + /// The actual error that occurred. + pub source: Box<dyn std::error::Error + Send + Sync + 'static>, + } + } } /// @@ -149,6 +184,25 @@ pub mod checkout_options { Attributes(#[from] super::attribute_stack::Error), #[error(transparent)] FilterPipelineOptions(#[from] crate::filter::pipeline::options::Error), + #[error(transparent)] + CommandContext(#[from] crate::config::command_context::Error), + } +} + +/// +#[cfg(feature = "attributes")] +pub mod command_context { + use crate::config; + + /// The error produced when collecting all information relevant to spawned commands, + /// obtained via [Repository::command_context()](crate::Repository::command_context()). + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + pub enum Error { + #[error(transparent)] + Boolean(#[from] config::boolean::Error), + #[error(transparent)] + ParseBool(#[from] gix_config::value::Error), } } @@ -409,6 +463,12 @@ pub mod refspec { } /// +pub mod refs_namespace { + /// The error produced when failing to parse a refspec from the configuration. + pub type Error = super::key::Error<gix_validate::reference::name::Error, 'v', 'i'>; +} + +/// pub mod ssl_version { /// The error produced when failing to parse a refspec from the configuration. pub type Error = super::key::Error<std::convert::Infallible, 's', 'i'>; @@ -504,6 +564,8 @@ pub(crate) struct Cache { pub use_multi_pack_index: bool, /// The representation of `core.logallrefupdates`, or `None` if the variable wasn't set. pub reflog: Option<gix_ref::store::WriteReflog>, + /// The representation of `gitoxide.core.refsNamespace`, or `None` if the variable wasn't set. + pub refs_namespace: Option<gix_ref::Namespace>, /// The configured user agent for presentation to servers. pub(crate) user_agent: OnceCell<String>, /// identities for later use, lazy initialization. @@ -512,7 +574,7 @@ pub(crate) struct Cache { pub(crate) url_rewrite: OnceCell<crate::remote::url::Rewrite>, /// The lazy-loaded rename information for diffs. #[cfg(feature = "blob-diff")] - pub(crate) diff_renames: OnceCell<Option<crate::object::tree::diff::Rewrites>>, + pub(crate) diff_renames: OnceCell<Option<crate::diff::Rewrites>>, /// A lazily loaded mapping to know which url schemes to allow #[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))] pub(crate) url_scheme: OnceCell<crate::remote::url::SchemePermission>, @@ -541,3 +603,23 @@ pub(crate) struct Cache { environment: crate::open::permissions::Environment, // TODO: make core.precomposeUnicode available as well. } + +/// Utillities shared privately across the crate, for lack of a better place. +pub(crate) mod shared { + use crate::{ + config, + config::{cache::util::ApplyLeniency, tree::Core}, + }; + + pub fn is_replace_refs_enabled( + config: &gix_config::File<'static>, + lenient: bool, + mut filter_config_section: fn(&gix_config::file::Metadata) -> bool, + ) -> Result<Option<bool>, config::boolean::Error> { + config + .boolean_filter_by_key("core.useReplaceRefs", &mut filter_config_section) + .map(|b| Core::USE_REPLACE_REFS.enrich_error(b)) + .transpose() + .with_leniency(lenient) + } +} diff --git a/vendor/gix/src/config/snapshot/access.rs b/vendor/gix/src/config/snapshot/access.rs index 7dc593880..6b98cf42d 100644 --- a/vendor/gix/src/config/snapshot/access.rs +++ b/vendor/gix/src/config/snapshot/access.rs @@ -4,9 +4,8 @@ use std::borrow::Cow; use gix_features::threading::OwnShared; use gix_macros::momo; -use crate::bstr::ByteSlice; use crate::{ - bstr::{BStr, BString}, + bstr::{BStr, BString, ByteSlice}, config::{CommitAutoRollback, Snapshot, SnapshotMut}, }; @@ -118,9 +117,13 @@ impl<'repo> SnapshotMut<'repo> { } let value = new_value.into(); key.validate(value)?; - let current = self - .config - .set_raw_value(key.section().name(), None, key.name(), value)?; + let section = key.section(); + let current = match section.parent() { + Some(parent) => self + .config + .set_raw_value(parent.name(), Some(section.name().into()), key.name(), value)?, + None => self.config.set_raw_value(section.name(), None, key.name(), value)?, + }; Ok(current.map(std::borrow::Cow::into_owned)) } diff --git a/vendor/gix/src/config/snapshot/credential_helpers.rs b/vendor/gix/src/config/snapshot/credential_helpers.rs index 189e74471..54499a1c3 100644 --- a/vendor/gix/src/config/snapshot/credential_helpers.rs +++ b/vendor/gix/src/config/snapshot/credential_helpers.rs @@ -2,11 +2,12 @@ use std::{borrow::Cow, convert::TryFrom}; pub use error::Error; -use crate::config::cache::util::IgnoreEmptyPath; +use crate::config::cache::util::ApplyLeniency; use crate::{ bstr::{ByteSlice, ByteVec}, config::{ - tree::{credential, Core, Credential, Key}, + cache::util::IgnoreEmptyPath, + tree::{credential, gitoxide::Credentials, Core, Credential, Key}, Snapshot, }, }; @@ -25,6 +26,8 @@ mod error { }, #[error("core.askpass could not be read")] CoreAskpass(#[from] gix_config::path::interpolate::Error), + #[error(transparent)] + BooleanConfig(#[from] crate::config::boolean::Error), } } @@ -144,16 +147,27 @@ impl Snapshot<'_> { .transpose() .ignore_empty()? .map(|c| Cow::Owned(c.into_owned())), - ..Default::default() + mode: self + .try_boolean(Credentials::TERMINAL_PROMPT.logical_name().as_str()) + .map(|val| Credentials::TERMINAL_PROMPT.enrich_error(val)) + .transpose() + .with_leniency(self.repo.config.lenient_config)? + .and_then(|val| (!val).then_some(gix_prompt::Mode::Disable)) + .unwrap_or_default(), } - .apply_environment(allow_git_env, allow_ssh_env, allow_git_env); + .apply_environment(allow_git_env, allow_ssh_env, false /* terminal prompt */); Ok(( gix_credentials::helper::Cascade { programs, use_http_path, // The default ssh implementation uses binaries that do their own auth, so our passwords aren't used. query_user_only: url.scheme == gix_url::Scheme::Ssh, - ..Default::default() + stderr: self + .try_boolean(Credentials::HELPER_STDERR.logical_name().as_str()) + .map(|val| Credentials::HELPER_STDERR.enrich_error(val)) + .transpose() + .with_leniency(self.repo.options.lenient_config)? + .unwrap_or(true), }, gix_credentials::helper::Action::get_for_url(url.to_bstring()), prompt_options, diff --git a/vendor/gix/src/config/tree/sections/core.rs b/vendor/gix/src/config/tree/sections/core.rs index 2ec5c279e..15ad9f947 100644 --- a/vendor/gix/src/config/tree/sections/core.rs +++ b/vendor/gix/src/config/tree/sections/core.rs @@ -8,13 +8,16 @@ impl Core { pub const ABBREV: Abbrev = Abbrev::new_with_validate("abbrev", &config::Tree::CORE, validate::Abbrev); /// The `core.bare` key. pub const BARE: keys::Boolean = keys::Boolean::new_boolean("bare", &config::Tree::CORE); + /// The `core.bigFileThreshold` key. + pub const BIG_FILE_THRESHOLD: keys::UnsignedInteger = + keys::UnsignedInteger::new_unsigned_integer("bigFileThreshold", &config::Tree::CORE); /// The `core.checkStat` key. pub const CHECK_STAT: CheckStat = CheckStat::new_with_validate("checkStat", &config::Tree::CORE, validate::CheckStat); /// The `core.deltaBaseCacheLimit` key. pub const DELTA_BASE_CACHE_LIMIT: keys::UnsignedInteger = keys::UnsignedInteger::new_unsigned_integer("deltaBaseCacheLimit", &config::Tree::CORE) - .with_environment_override("GITOXIDE_PACK_CACHE_MEMORY") + .with_environment_override("GIX_PACK_CACHE_MEMORY") .with_note("if unset, we default to a small 64 slot fixed-size cache that holds at most 64 full delta base objects of any size. Set to 0 to deactivate it entirely"); /// The `core.disambiguate` key. pub const DISAMBIGUATE: Disambiguate = @@ -95,6 +98,7 @@ impl Section for Core { &[ &Self::ABBREV, &Self::BARE, + &Self::BIG_FILE_THRESHOLD, &Self::CHECK_STAT, &Self::DELTA_BASE_CACHE_LIMIT, &Self::DISAMBIGUATE, diff --git a/vendor/gix/src/config/tree/sections/diff.rs b/vendor/gix/src/config/tree/sections/diff.rs index 7c467b8f5..0ebc13711 100644 --- a/vendor/gix/src/config/tree/sections/diff.rs +++ b/vendor/gix/src/config/tree/sections/diff.rs @@ -1,6 +1,6 @@ use crate::{ config, - config::tree::{keys, Diff, Key, Section}, + config::tree::{keys, Diff, Key, Section, SubSectionRequirement}, }; impl Diff { @@ -17,6 +17,24 @@ impl Diff { ); /// The `diff.renames` key. pub const RENAMES: Renames = Renames::new_renames("renames", &config::Tree::DIFF); + + /// The `diff.<driver>.command` key. + pub const DRIVER_COMMAND: keys::String = keys::String::new_string("command", &config::Tree::DIFF) + .with_subsection_requirement(Some(SubSectionRequirement::Parameter("driver"))); + /// The `diff.<driver>.textconv` key. + pub const DRIVER_TEXTCONV: keys::String = keys::String::new_string("textconv", &config::Tree::DIFF) + .with_subsection_requirement(Some(SubSectionRequirement::Parameter("driver"))); + /// The `diff.<driver>.algorithm` key. + pub const DRIVER_ALGORITHM: Algorithm = + Algorithm::new_with_validate("algorithm", &config::Tree::DIFF, validate::Algorithm) + .with_subsection_requirement(Some(SubSectionRequirement::Parameter("driver"))); + /// The `diff.<driver>.binary` key. + pub const DRIVER_BINARY: Binary = Binary::new_with_validate("binary", &config::Tree::DIFF, validate::Binary) + .with_subsection_requirement(Some(SubSectionRequirement::Parameter("driver"))); + + /// The `diff.external` key. + pub const EXTERNAL: keys::Program = + keys::Program::new_program("external", &config::Tree::DIFF).with_environment_override("GIT_EXTERNAL_DIFF"); } impl Section for Diff { @@ -25,7 +43,16 @@ impl Section for Diff { } fn keys(&self) -> &[&dyn Key] { - &[&Self::ALGORITHM, &Self::RENAME_LIMIT, &Self::RENAMES] + &[ + &Self::ALGORITHM, + &Self::RENAME_LIMIT, + &Self::RENAMES, + &Self::DRIVER_COMMAND, + &Self::DRIVER_TEXTCONV, + &Self::DRIVER_ALGORITHM, + &Self::DRIVER_BINARY, + &Self::EXTERNAL, + ] } } @@ -35,6 +62,9 @@ pub type Algorithm = keys::Any<validate::Algorithm>; /// The `diff.renames` key. pub type Renames = keys::Any<validate::Renames>; +/// The `diff.<driver>.binary` key. +pub type Binary = keys::Any<validate::Binary>; + mod algorithm { use std::borrow::Cow; @@ -67,6 +97,38 @@ mod algorithm { } } +mod binary { + use crate::config::tree::diff::Binary; + + impl Binary { + /// Convert `value` into a tri-state boolean that can take the special value `auto`, resulting in `None`, or is a boolean. + /// If `None` is given, it's treated as implicit boolean `true`, as this method is made to be used + /// with [`gix_config::file::section::Body::value_implicit()`]. + pub fn try_into_binary( + &'static self, + value: Option<std::borrow::Cow<'_, crate::bstr::BStr>>, + ) -> Result<Option<bool>, crate::config::key::GenericErrorWithValue> { + Ok(match value { + None => Some(true), + Some(value) => { + if value.as_ref() == "auto" { + None + } else { + Some( + gix_config::Boolean::try_from(value.as_ref()) + .map(|b| b.0) + .map_err(|err| { + crate::config::key::GenericErrorWithValue::from_value(self, value.into_owned()) + .with_source(err) + })?, + ) + } + } + }) + } + } +} + mod renames { use crate::{ bstr::ByteSlice, @@ -125,4 +187,12 @@ mod validate { Ok(()) } } + + pub struct Binary; + impl keys::Validate for Binary { + fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> { + Diff::DRIVER_BINARY.try_into_binary(Some(value.into()))?; + Ok(()) + } + } } diff --git a/vendor/gix/src/config/tree/sections/fetch.rs b/vendor/gix/src/config/tree/sections/fetch.rs index 32db7be5f..9b618913d 100644 --- a/vendor/gix/src/config/tree/sections/fetch.rs +++ b/vendor/gix/src/config/tree/sections/fetch.rs @@ -45,8 +45,7 @@ mod algorithm { &'static self, name: std::borrow::Cow<'_, crate::bstr::BStr>, ) -> Result<crate::remote::fetch::negotiate::Algorithm, crate::config::key::GenericErrorWithValue> { - use crate::bstr::ByteSlice; - use crate::remote::fetch::negotiate::Algorithm; + use crate::{bstr::ByteSlice, remote::fetch::negotiate::Algorithm}; Ok(match name.as_ref().as_bytes() { b"noop" => Algorithm::Noop, diff --git a/vendor/gix/src/config/tree/sections/gitoxide.rs b/vendor/gix/src/config/tree/sections/gitoxide.rs index 966d5af7c..a3b054412 100644 --- a/vendor/gix/src/config/tree/sections/gitoxide.rs +++ b/vendor/gix/src/config/tree/sections/gitoxide.rs @@ -14,6 +14,8 @@ impl Gitoxide { pub const COMMIT: Commit = Commit; /// The `gitoxide.committer` section. pub const COMMITTER: Committer = Committer; + /// The `gitoxide.credentials` section. + pub const CREDENTIALS: Credentials = Credentials; /// The `gitoxide.http` section. pub const HTTP: Http = Http; /// The `gitoxide.https` section. @@ -31,6 +33,9 @@ impl Gitoxide { pub const USER_AGENT: keys::Any = keys::Any::new("userAgent", &config::Tree::GITOXIDE).with_note( "The user agent presented on the git protocol layer, serving as fallback for when no `http.userAgent` is set", ); + /// The `gitoxide.tracePacket` Key. + pub const TRACE_PACKET: keys::Boolean = keys::Boolean::new_boolean("tracePacket", &config::Tree::GITOXIDE) + .with_environment_override("GIT_TRACE_PACKET"); } impl Section for Gitoxide { @@ -39,7 +44,7 @@ impl Section for Gitoxide { } fn keys(&self) -> &[&dyn Key] { - &[&Self::USER_AGENT] + &[&Self::USER_AGENT, &Self::TRACE_PACKET] } fn sub_sections(&self) -> &[&dyn Section] { @@ -49,6 +54,7 @@ impl Section for Gitoxide { &Self::CORE, &Self::COMMIT, &Self::COMMITTER, + &Self::CREDENTIALS, &Self::HTTP, &Self::HTTPS, &Self::OBJECTS, @@ -69,6 +75,20 @@ mod subsections { #[derive(Copy, Clone, Default)] pub struct Core; + /// The `gitoxide.allow.protocolFromUser` key. + pub type RefsNamespace = keys::Any<super::validate::RefsNamespace>; + + impl RefsNamespace { + /// Derive the negotiation algorithm identified by `name`, case-sensitively. + pub fn try_into_refs_namespace( + &'static self, + name: std::borrow::Cow<'_, crate::bstr::BStr>, + ) -> Result<gix_ref::Namespace, crate::config::refs_namespace::Error> { + gix_ref::namespace::expand(name.as_ref()) + .map_err(|err| crate::config::key::Error::from_value(self, name.into_owned()).with_source(err)) + } + } + impl Core { /// The `gitoxide.core.defaultPackCacheMemoryLimit` key. pub const DEFAULT_PACK_CACHE_MEMORY_LIMIT: keys::UnsignedInteger = @@ -95,6 +115,20 @@ mod subsections { /// It controls whether or not long running filter driver processes can use the 'delay' capability. pub const FILTER_PROCESS_DELAY: keys::Boolean = keys::Boolean::new_boolean("filterProcessDelay", &Gitoxide::CORE); + + /// The `gitoxide.core.externalCommandStderr` key (default `true`). + /// + /// If `true`, the default, `stderr` of worktree filter programs, or any other git-context bearing command + /// invoked will be inherited. + /// If `false`, it will be suppressed completely. + pub const EXTERNAL_COMMAND_STDERR: keys::Boolean = + keys::Boolean::new_boolean("externalCommandStderr", &Gitoxide::CORE) + .with_environment_override("GIX_EXTERNAL_COMMAND_STDERR"); + + /// The `gitoxide.core.refsNamespace` key. + pub const REFS_NAMESPACE: RefsNamespace = + keys::Any::new_with_validate("refsNamespace", &Gitoxide::CORE, super::validate::RefsNamespace) + .with_environment_override("GIT_NAMESPACE"); } impl Section for Core { @@ -109,6 +143,8 @@ mod subsections { &Self::USE_STDEV, &Self::SHALLOW_FILE, &Self::FILTER_PROCESS_DELAY, + &Self::EXTERNAL_COMMAND_STDERR, + &Self::REFS_NAMESPACE, ] } @@ -154,6 +190,14 @@ mod subsections { http::SslVersion::new_ssl_version("sslVersionMax", &Gitoxide::HTTP).with_note( "entirely new to set the upper bound for the allowed ssl version range. Overwrites the max bound of `http.sslVersion` if set. Min and Max must be set to become effective.", ); + /// The `gitoxide.http.sslNoVerify` key. + /// + /// If set, disable SSL verification. Using this is discouraged as it can lead to + /// various security risks. An example where this may be needed is when an internal + /// git server uses a self-signed certificate and the user accepts the associated security risks. + pub const SSL_NO_VERIFY: keys::Boolean = keys::Boolean::new_boolean("sslNoVerify", &Gitoxide::HTTP) + .with_environment_override("GIT_SSL_NO_VERIFY") + .with_note("used to disable SSL verification. When this is enabled it takes priority over http.sslVerify"); /// The `gitoxide.http.proxyAuthMethod` key. pub const PROXY_AUTH_METHOD: http::ProxyAuthMethod = http::ProxyAuthMethod::new_proxy_auth_method("proxyAuthMethod", &Gitoxide::HTTP) @@ -174,6 +218,7 @@ mod subsections { &Self::CONNECT_TIMEOUT, &Self::SSL_VERSION_MIN, &Self::SSL_VERSION_MAX, + &Self::SSL_NO_VERIFY, &Self::PROXY_AUTH_METHOD, ] } @@ -375,7 +420,7 @@ mod subsections { pub const CACHE_LIMIT: keys::UnsignedInteger = keys::UnsignedInteger::new_unsigned_integer("cacheLimit", &Gitoxide::OBJECTS) .with_note("If unset or 0, there is no object cache") - .with_environment_override("GITOXIDE_OBJECT_CACHE_MEMORY"); + .with_environment_override("GIX_OBJECT_CACHE_MEMORY"); /// The `gitoxide.objects.noReplace` key. pub const NO_REPLACE: keys::Boolean = keys::Boolean::new_boolean("noReplace", &Gitoxide::OBJECTS); /// The `gitoxide.objects.replaceRefBase` key. @@ -424,6 +469,37 @@ mod subsections { } } + /// The `credentials` sub-section. + #[derive(Copy, Clone, Default)] + pub struct Credentials; + impl Credentials { + /// The `gitoxide.credentials.terminalPrompt` key. + pub const TERMINAL_PROMPT: keys::Boolean = keys::Boolean::new_boolean("terminalPrompt", &Gitoxide::CREDENTIALS) + .with_note("This is a custom addition to provide an alternative to the respective environment variable.") + .with_environment_override("GIT_TERMINAL_PROMPT"); + + /// The `gitoxide.credentials.helperStderr` key to control what happens with the credential helpers `stderr`. + /// + /// If `true`, the default, `stderr` of credential helper programs will be inherited, just like with `git`. + /// If `false`, will be suppressed completely. + pub const HELPER_STDERR: keys::Boolean = keys::Boolean::new_boolean("helperStderr", &Gitoxide::CREDENTIALS) + .with_environment_override("GIX_CREDENTIALS_HELPER_STDERR"); + } + + impl Section for Credentials { + fn name(&self) -> &str { + "credentials" + } + + fn keys(&self) -> &[&dyn Key] { + &[&Self::TERMINAL_PROMPT, &Self::HELPER_STDERR] + } + + fn parent(&self) -> Option<&dyn Section> { + Some(&Tree::GITOXIDE) + } + } + /// The `commit` sub-section. #[derive(Copy, Clone, Default)] pub struct Commit; @@ -451,7 +527,7 @@ mod subsections { } } } -pub use subsections::{Allow, Author, Commit, Committer, Core, Http, Https, Objects, Pathspec, Ssh, User}; +pub use subsections::{Allow, Author, Commit, Committer, Core, Credentials, Http, Https, Objects, Pathspec, Ssh, User}; pub mod validate { use std::error::Error; @@ -467,4 +543,12 @@ pub mod validate { Ok(()) } } + + pub struct RefsNamespace; + impl Validate for RefsNamespace { + fn validate(&self, value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> { + super::Core::REFS_NAMESPACE.try_into_refs_namespace(value.into())?; + Ok(()) + } + } } diff --git a/vendor/gix/src/config/tree/sections/http.rs b/vendor/gix/src/config/tree/sections/http.rs index f45c37076..4fc733564 100644 --- a/vendor/gix/src/config/tree/sections/http.rs +++ b/vendor/gix/src/config/tree/sections/http.rs @@ -10,6 +10,9 @@ impl Http { .with_deviation( "accepts the new 'default' value which means to use the curl default just like the empty string does", ); + /// The `http.sslVerify` key. + pub const SSL_VERIFY: keys::Boolean = keys::Boolean::new_boolean("sslVerify", &config::Tree::HTTP) + .with_note("also see the `gitoxide.http.sslNoVerify` key"); /// The `http.proxy` key. pub const PROXY: keys::String = keys::String::new_string("proxy", &config::Tree::HTTP).with_deviation("fails on strings with illformed UTF-8"); @@ -58,6 +61,7 @@ impl Section for Http { fn keys(&self) -> &[&dyn Key] { &[ &Self::SSL_VERSION, + &Self::SSL_VERIFY, &Self::PROXY, &Self::PROXY_AUTH_METHOD, &Self::VERSION, |