summaryrefslogtreecommitdiffstats
path: root/vendor/gix/src/config/tree/sections
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix/src/config/tree/sections')
-rw-r--r--vendor/gix/src/config/tree/sections/author.rs23
-rw-r--r--vendor/gix/src/config/tree/sections/branch.rs65
-rw-r--r--vendor/gix/src/config/tree/sections/checkout.rs58
-rw-r--r--vendor/gix/src/config/tree/sections/clone.rs20
-rw-r--r--vendor/gix/src/config/tree/sections/committer.rs23
-rw-r--r--vendor/gix/src/config/tree/sections/core.rs302
-rw-r--r--vendor/gix/src/config/tree/sections/credential.rs56
-rw-r--r--vendor/gix/src/config/tree/sections/diff.rs133
-rw-r--r--vendor/gix/src/config/tree/sections/extensions.rs59
-rw-r--r--vendor/gix/src/config/tree/sections/gitoxide.rs363
-rw-r--r--vendor/gix/src/config/tree/sections/http.rs317
-rw-r--r--vendor/gix/src/config/tree/sections/init.rs20
-rw-r--r--vendor/gix/src/config/tree/sections/mod.rs96
-rw-r--r--vendor/gix/src/config/tree/sections/pack.rs64
-rw-r--r--vendor/gix/src/config/tree/sections/protocol.rs85
-rw-r--r--vendor/gix/src/config/tree/sections/remote.rs101
-rw-r--r--vendor/gix/src/config/tree/sections/safe.rs27
-rw-r--r--vendor/gix/src/config/tree/sections/ssh.rs65
-rw-r--r--vendor/gix/src/config/tree/sections/url.rs25
-rw-r--r--vendor/gix/src/config/tree/sections/user.rs22
20 files changed, 1924 insertions, 0 deletions
diff --git a/vendor/gix/src/config/tree/sections/author.rs b/vendor/gix/src/config/tree/sections/author.rs
new file mode 100644
index 000000000..4101e3817
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/author.rs
@@ -0,0 +1,23 @@
+use crate::{
+ config,
+ config::tree::{gitoxide, keys, Author, Key, Section},
+};
+
+impl Author {
+ /// The `author.name` key.
+ pub const NAME: keys::Any =
+ keys::Any::new("name", &config::Tree::AUTHOR).with_fallback(&gitoxide::Author::NAME_FALLBACK);
+ /// The `author.email` key.
+ pub const EMAIL: keys::Any =
+ keys::Any::new("email", &config::Tree::AUTHOR).with_fallback(&gitoxide::Author::EMAIL_FALLBACK);
+}
+
+impl Section for Author {
+ fn name(&self) -> &str {
+ "author"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::NAME, &Self::EMAIL]
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/branch.rs b/vendor/gix/src/config/tree/sections/branch.rs
new file mode 100644
index 000000000..8e1e0a4b8
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/branch.rs
@@ -0,0 +1,65 @@
+use crate::config::tree::{keys, traits::SubSectionRequirement, Branch, Key, Section};
+
+const NAME_PARAMETER: Option<SubSectionRequirement> = Some(SubSectionRequirement::Parameter("name"));
+
+impl Branch {
+ /// The `branch.<name>.merge` key.
+ pub const MERGE: Merge = Merge::new_with_validate("merge", &crate::config::Tree::BRANCH, validate::FullNameRef)
+ .with_subsection_requirement(NAME_PARAMETER);
+ /// The `branch.<name>.pushRemote` key.
+ pub const PUSH_REMOTE: keys::RemoteName =
+ keys::RemoteName::new_remote_name("pushRemote", &crate::config::Tree::BRANCH)
+ .with_subsection_requirement(NAME_PARAMETER);
+ /// The `branch.<name>.remote` key.
+ pub const REMOTE: keys::RemoteName = keys::RemoteName::new_remote_name("remote", &crate::config::Tree::BRANCH)
+ .with_subsection_requirement(NAME_PARAMETER);
+}
+
+impl Section for Branch {
+ fn name(&self) -> &str {
+ "branch"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::MERGE, &Self::PUSH_REMOTE, &Self::REMOTE]
+ }
+}
+
+/// The `branch.<name>.merge` key.
+pub type Merge = keys::Any<validate::FullNameRef>;
+
+mod merge {
+ use std::borrow::Cow;
+
+ use gix_ref::FullNameRef;
+
+ use crate::{bstr::BStr, config::tree::branch::Merge};
+
+ impl Merge {
+ /// Return the validated full ref name from `value` if it is valid.
+ pub fn try_into_fullrefname(
+ value: Cow<'_, BStr>,
+ ) -> Result<Cow<'_, FullNameRef>, gix_validate::reference::name::Error> {
+ match value {
+ Cow::Borrowed(v) => v.try_into().map(Cow::Borrowed),
+ Cow::Owned(v) => v.try_into().map(Cow::Owned),
+ }
+ }
+ }
+}
+
+///
+pub mod validate {
+ use crate::{
+ bstr::BStr,
+ config::tree::{branch::Merge, keys},
+ };
+
+ pub struct FullNameRef;
+ impl keys::Validate for FullNameRef {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ Merge::try_into_fullrefname(value.into())?;
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/checkout.rs b/vendor/gix/src/config/tree/sections/checkout.rs
new file mode 100644
index 000000000..27f31ee84
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/checkout.rs
@@ -0,0 +1,58 @@
+use crate::{
+ config,
+ config::tree::{keys, Checkout, Key, Section},
+};
+
+impl Checkout {
+ /// The `checkout.workers` key.
+ pub const WORKERS: Workers = Workers::new_with_validate("workers", &config::Tree::CHECKOUT, validate::Workers)
+ .with_deviation("if unset, uses all cores instead of just one");
+}
+
+/// The `checkout.workers` key.
+pub type Workers = keys::Any<validate::Workers>;
+
+impl Section for Checkout {
+ fn name(&self) -> &str {
+ "checkout"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::WORKERS]
+ }
+}
+
+mod workers {
+ use crate::config::tree::checkout::Workers;
+
+ impl Workers {
+ /// Return the amount of threads to use for checkout, with `0` meaning all available ones, after decoding our integer value from `config`,
+ /// or `None` if the value isn't set which is typically interpreted as "as many threads as available"
+ pub fn try_from_workers(
+ &'static self,
+ value: Result<i64, gix_config::value::Error>,
+ ) -> Result<usize, crate::config::checkout::workers::Error> {
+ match value {
+ Ok(v) if v < 0 => Ok(0),
+ Ok(v) => Ok(v.try_into().expect("positive i64 can always be usize on 64 bit")),
+ Err(err) => Err(crate::config::key::Error::from(&super::Checkout::WORKERS).with_source(err)),
+ }
+ }
+ }
+}
+
+///
+pub mod validate {
+ use crate::{bstr::BStr, config::tree::keys};
+
+ pub struct Workers;
+ impl keys::Validate for Workers {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ super::Checkout::WORKERS.try_from_workers(gix_config::Integer::try_from(value).and_then(|i| {
+ i.to_decimal()
+ .ok_or_else(|| gix_config::value::Error::new("Integer overflow", value.to_owned()))
+ }))?;
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/clone.rs b/vendor/gix/src/config/tree/sections/clone.rs
new file mode 100644
index 000000000..616185a0b
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/clone.rs
@@ -0,0 +1,20 @@
+use crate::{
+ config,
+ config::tree::{keys, Clone, Key, Section},
+};
+
+impl Clone {
+ /// The `clone.defaultRemoteName` key.
+ pub const DEFAULT_REMOTE_NAME: keys::RemoteName =
+ keys::RemoteName::new_remote_name("defaultRemoteName", &config::Tree::CLONE);
+}
+
+impl Section for Clone {
+ fn name(&self) -> &str {
+ "clone"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::DEFAULT_REMOTE_NAME]
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/committer.rs b/vendor/gix/src/config/tree/sections/committer.rs
new file mode 100644
index 000000000..acc25c930
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/committer.rs
@@ -0,0 +1,23 @@
+use crate::{
+ config,
+ config::tree::{gitoxide, keys, Committer, Key, Section},
+};
+
+impl Committer {
+ /// The `committer.name` key.
+ pub const NAME: keys::Any =
+ keys::Any::new("name", &config::Tree::COMMITTER).with_fallback(&gitoxide::Committer::NAME_FALLBACK);
+ /// The `committer.email` key.
+ pub const EMAIL: keys::Any =
+ keys::Any::new("email", &config::Tree::COMMITTER).with_fallback(&gitoxide::Committer::EMAIL_FALLBACK);
+}
+
+impl Section for Committer {
+ fn name(&self) -> &str {
+ "committer"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::NAME, &Self::EMAIL]
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/core.rs b/vendor/gix/src/config/tree/sections/core.rs
new file mode 100644
index 000000000..6ea0580e1
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/core.rs
@@ -0,0 +1,302 @@
+use crate::{
+ config,
+ config::tree::{keys, Core, Key, Section},
+};
+
+impl Core {
+ /// The `core.abbrev` key.
+ 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.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_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 =
+ Disambiguate::new_with_validate("disambiguate", &config::Tree::CORE, validate::Disambiguate);
+ /// The `core.fileMode` key.
+ pub const FILE_MODE: keys::Boolean = keys::Boolean::new_boolean("fileMode", &config::Tree::CORE);
+ /// The `core.ignoreCase` key.
+ pub const IGNORE_CASE: keys::Boolean = keys::Boolean::new_boolean("ignoreCase", &config::Tree::CORE);
+ /// The `core.filesRefLockTimeout` key.
+ pub const FILES_REF_LOCK_TIMEOUT: keys::LockTimeout =
+ keys::LockTimeout::new_lock_timeout("filesRefLockTimeout", &config::Tree::CORE);
+ /// The `core.packedRefsTimeout` key.
+ pub const PACKED_REFS_TIMEOUT: keys::LockTimeout =
+ keys::LockTimeout::new_lock_timeout("packedRefsTimeout", &config::Tree::CORE);
+ /// The `core.multiPackIndex` key.
+ pub const MULTIPACK_INDEX: keys::Boolean = keys::Boolean::new_boolean("multiPackIndex", &config::Tree::CORE);
+ /// The `core.logAllRefUpdates` key.
+ pub const LOG_ALL_REF_UPDATES: LogAllRefUpdates =
+ LogAllRefUpdates::new_with_validate("logAllRefUpdates", &config::Tree::CORE, validate::LogAllRefUpdates);
+ /// The `core.precomposeUnicode` key.
+ ///
+ /// Needs application to use [env::args_os][crate::env::args_os()] to conform all input paths before they are used.
+ pub const PRECOMPOSE_UNICODE: keys::Boolean = keys::Boolean::new_boolean("precomposeUnicode", &config::Tree::CORE)
+ .with_note("application needs to conform all program input by using gix::env::args_os()");
+ /// The `core.repositoryFormatVersion` key.
+ pub const REPOSITORY_FORMAT_VERSION: keys::UnsignedInteger =
+ keys::UnsignedInteger::new_unsigned_integer("repositoryFormatVersion", &config::Tree::CORE);
+ /// The `core.symlinks` key.
+ pub const SYMLINKS: keys::Boolean = keys::Boolean::new_boolean("symlinks", &config::Tree::CORE);
+ /// The `core.trustCTime` key.
+ pub const TRUST_C_TIME: keys::Boolean = keys::Boolean::new_boolean("trustCTime", &config::Tree::CORE);
+ /// The `core.worktree` key.
+ pub const WORKTREE: keys::Any = keys::Any::new("worktree", &config::Tree::CORE)
+ .with_environment_override("GIT_WORK_TREE")
+ .with_deviation("Overriding the worktree with environment variables is supported using `ThreadSafeRepository::open_with_environment_overrides()");
+ /// The `core.askPass` key.
+ pub const ASKPASS: keys::Executable = keys::Executable::new_executable("askPass", &config::Tree::CORE)
+ .with_environment_override("GIT_ASKPASS")
+ .with_note("fallback is 'SSH_ASKPASS'");
+ /// The `core.excludesFile` key.
+ pub const EXCLUDES_FILE: keys::Executable = keys::Executable::new_executable("excludesFile", &config::Tree::CORE);
+ /// The `core.attributesFile` key.
+ pub const ATTRIBUTES_FILE: keys::Executable =
+ keys::Executable::new_executable("attributesFile", &config::Tree::CORE)
+ .with_deviation("for checkout - it's already queried but needs building of attributes group, and of course support during checkout");
+ /// The `core.sshCommand` key.
+ pub const SSH_COMMAND: keys::Executable = keys::Executable::new_executable("sshCommand", &config::Tree::CORE)
+ .with_environment_override("GIT_SSH_COMMAND");
+}
+
+impl Section for Core {
+ fn name(&self) -> &str {
+ "core"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[
+ &Self::ABBREV,
+ &Self::BARE,
+ &Self::CHECK_STAT,
+ &Self::DELTA_BASE_CACHE_LIMIT,
+ &Self::DISAMBIGUATE,
+ &Self::FILE_MODE,
+ &Self::IGNORE_CASE,
+ &Self::FILES_REF_LOCK_TIMEOUT,
+ &Self::PACKED_REFS_TIMEOUT,
+ &Self::MULTIPACK_INDEX,
+ &Self::LOG_ALL_REF_UPDATES,
+ &Self::PRECOMPOSE_UNICODE,
+ &Self::REPOSITORY_FORMAT_VERSION,
+ &Self::SYMLINKS,
+ &Self::TRUST_C_TIME,
+ &Self::WORKTREE,
+ &Self::ASKPASS,
+ &Self::EXCLUDES_FILE,
+ &Self::ATTRIBUTES_FILE,
+ &Self::SSH_COMMAND,
+ ]
+ }
+}
+
+/// The `core.checkStat` key.
+pub type CheckStat = keys::Any<validate::CheckStat>;
+
+/// The `core.abbrev` key.
+pub type Abbrev = keys::Any<validate::Abbrev>;
+
+/// The `core.logAllRefUpdates` key.
+pub type LogAllRefUpdates = keys::Any<validate::LogAllRefUpdates>;
+
+/// The `core.disambiguate` key.
+pub type Disambiguate = keys::Any<validate::Disambiguate>;
+
+mod disambiguate {
+ use std::borrow::Cow;
+
+ use crate::{
+ bstr::{BStr, ByteSlice},
+ config,
+ config::tree::core::Disambiguate,
+ revision::spec::parse::ObjectKindHint,
+ };
+
+ impl Disambiguate {
+ /// Convert a disambiguation marker into the respective enum.
+ pub fn try_into_object_kind_hint(
+ &'static self,
+ value: Cow<'_, BStr>,
+ ) -> Result<Option<ObjectKindHint>, config::key::GenericErrorWithValue> {
+ let hint = match value.as_ref().as_bytes() {
+ b"none" => return Ok(None),
+ b"commit" => ObjectKindHint::Commit,
+ b"committish" => ObjectKindHint::Committish,
+ b"tree" => ObjectKindHint::Tree,
+ b"treeish" => ObjectKindHint::Treeish,
+ b"blob" => ObjectKindHint::Blob,
+ _ => return Err(config::key::GenericErrorWithValue::from_value(self, value.into_owned())),
+ };
+ Ok(Some(hint))
+ }
+ }
+}
+
+mod log_all_ref_updates {
+ use std::borrow::Cow;
+
+ use crate::{bstr::BStr, config, config::tree::core::LogAllRefUpdates};
+
+ impl LogAllRefUpdates {
+ /// Returns the mode for ref-updates as parsed from `value`. If `value` is not a boolean, `string_on_failure` will be called
+ /// to obtain the key `core.logAllRefUpdates` as string instead. For correctness, this two step process is necessary as
+ /// the interpretation of booleans in special in `gix-config`, i.e. we can't just treat it as string.
+ pub fn try_into_ref_updates<'a>(
+ &'static self,
+ value: Option<Result<bool, gix_config::value::Error>>,
+ string_on_failure: impl FnOnce() -> Option<Cow<'a, BStr>>,
+ ) -> Result<Option<gix_ref::store::WriteReflog>, config::key::GenericErrorWithValue> {
+ match value.transpose().ok().flatten() {
+ Some(bool) => Ok(Some(if bool {
+ gix_ref::store::WriteReflog::Normal
+ } else {
+ gix_ref::store::WriteReflog::Disable
+ })),
+ None => match string_on_failure() {
+ Some(val) if val.eq_ignore_ascii_case(b"always") => Ok(Some(gix_ref::store::WriteReflog::Always)),
+ Some(val) => Err(config::key::GenericErrorWithValue::from_value(self, val.into_owned())),
+ None => Ok(None),
+ },
+ }
+ }
+ }
+}
+
+mod check_stat {
+ use std::borrow::Cow;
+
+ use crate::{
+ bstr::{BStr, ByteSlice},
+ config,
+ config::tree::core::CheckStat,
+ };
+
+ impl CheckStat {
+ /// Returns true if the full set of stat entries should be checked, and it's just as lenient as git.
+ pub fn try_into_checkstat(
+ &'static self,
+ value: Cow<'_, BStr>,
+ ) -> Result<bool, config::key::GenericErrorWithValue> {
+ Ok(match value.as_ref().as_bytes() {
+ b"minimal" => false,
+ b"default" => true,
+ _ => {
+ return Err(config::key::GenericErrorWithValue::from_value(self, value.into_owned()));
+ }
+ })
+ }
+ }
+}
+
+mod abbrev {
+ use std::borrow::Cow;
+
+ use config::abbrev::Error;
+
+ use crate::{
+ bstr::{BStr, ByteSlice},
+ config,
+ config::tree::core::Abbrev,
+ };
+
+ impl Abbrev {
+ /// Convert the given `hex_len_str` into the amount of characters that a short hash should have.
+ /// If `None` is returned, the correct value can be determined based on the amount of objects in the repo.
+ pub fn try_into_abbreviation(
+ &'static self,
+ hex_len_str: Cow<'_, BStr>,
+ object_hash: gix_hash::Kind,
+ ) -> Result<Option<usize>, Error> {
+ let max = object_hash.len_in_hex() as u8;
+ if hex_len_str.trim().is_empty() {
+ return Err(Error {
+ value: hex_len_str.into_owned(),
+ max,
+ });
+ }
+ if hex_len_str.trim().eq_ignore_ascii_case(b"auto") {
+ Ok(None)
+ } else {
+ let value_bytes = hex_len_str.as_ref();
+ if let Ok(false) = gix_config::Boolean::try_from(value_bytes).map(Into::into) {
+ Ok(object_hash.len_in_hex().into())
+ } else {
+ let value = gix_config::Integer::try_from(value_bytes)
+ .map_err(|_| Error {
+ value: hex_len_str.clone().into_owned(),
+ max,
+ })?
+ .to_decimal()
+ .ok_or_else(|| Error {
+ value: hex_len_str.clone().into_owned(),
+ max,
+ })?;
+ if value < 4 || value as usize > object_hash.len_in_hex() {
+ return Err(Error {
+ value: hex_len_str.clone().into_owned(),
+ max,
+ });
+ }
+ Ok(Some(value as usize))
+ }
+ }
+ }
+ }
+}
+
+mod validate {
+ use crate::{bstr::BStr, config::tree::keys};
+
+ pub struct LockTimeout;
+ impl keys::Validate for LockTimeout {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ let value = gix_config::Integer::try_from(value)?
+ .to_decimal()
+ .ok_or_else(|| format!("integer {value} cannot be represented as integer"));
+ super::Core::FILES_REF_LOCK_TIMEOUT.try_into_lock_timeout(Ok(value?))?;
+ Ok(())
+ }
+ }
+
+ pub struct Disambiguate;
+ impl keys::Validate for Disambiguate {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ super::Core::DISAMBIGUATE.try_into_object_kind_hint(value.into())?;
+ Ok(())
+ }
+ }
+
+ pub struct LogAllRefUpdates;
+ impl keys::Validate for LogAllRefUpdates {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ super::Core::LOG_ALL_REF_UPDATES
+ .try_into_ref_updates(Some(gix_config::Boolean::try_from(value).map(|b| b.0)), || {
+ Some(value.into())
+ })?;
+ Ok(())
+ }
+ }
+
+ pub struct CheckStat;
+ impl keys::Validate for CheckStat {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ super::Core::CHECK_STAT.try_into_checkstat(value.into())?;
+ Ok(())
+ }
+ }
+
+ pub struct Abbrev;
+ impl keys::Validate for Abbrev {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ // TODO: when there is options, validate against all hashes and assure all fail to trigger a validation failure.
+ super::Core::ABBREV.try_into_abbreviation(value.into(), gix_hash::Kind::Sha1)?;
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/credential.rs b/vendor/gix/src/config/tree/sections/credential.rs
new file mode 100644
index 000000000..d370db0c5
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/credential.rs
@@ -0,0 +1,56 @@
+use crate::{
+ config,
+ config::tree::{keys, Credential, Key, Section},
+};
+
+impl Credential {
+ /// The `credential.helper` key.
+ pub const HELPER: keys::Program = keys::Program::new_program("helper", &config::Tree::CREDENTIAL);
+ /// The `credential.username` key.
+ pub const USERNAME: keys::Any = keys::Any::new("username", &config::Tree::CREDENTIAL);
+ /// The `credential.useHttpPath` key.
+ pub const USE_HTTP_PATH: keys::Boolean = keys::Boolean::new_boolean("useHttpPath", &config::Tree::CREDENTIAL);
+
+ /// The `credential.<url>` subsection
+ pub const URL_PARAMETER: UrlParameter = UrlParameter;
+}
+
+/// The `credential.<url>` parameter section.
+pub struct UrlParameter;
+
+impl UrlParameter {
+ /// The `credential.<url>.helper` key.
+ pub const HELPER: keys::Program = keys::Program::new_program("helper", &Credential::URL_PARAMETER);
+ /// The `credential.<url>.username` key.
+ pub const USERNAME: keys::Any = keys::Any::new("username", &Credential::URL_PARAMETER);
+ /// The `credential.<url>.useHttpPath` key.
+ pub const USE_HTTP_PATH: keys::Boolean = keys::Boolean::new_boolean("useHttpPath", &Credential::URL_PARAMETER);
+}
+
+impl Section for UrlParameter {
+ fn name(&self) -> &str {
+ "<url>"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::HELPER, &Self::USERNAME, &Self::USE_HTTP_PATH]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&config::Tree::CREDENTIAL)
+ }
+}
+
+impl Section for Credential {
+ fn name(&self) -> &str {
+ "credential"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::HELPER, &Self::USERNAME, &Self::USE_HTTP_PATH]
+ }
+
+ fn sub_sections(&self) -> &[&dyn Section] {
+ &[&Self::URL_PARAMETER]
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/diff.rs b/vendor/gix/src/config/tree/sections/diff.rs
new file mode 100644
index 000000000..103bb7001
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/diff.rs
@@ -0,0 +1,133 @@
+use crate::{
+ config,
+ config::tree::{keys, Diff, Key, Section},
+};
+
+impl Diff {
+ /// The `diff.algorithm` key.
+ pub const ALGORITHM: Algorithm = Algorithm::new_with_validate("algorithm", &config::Tree::DIFF, validate::Algorithm)
+ .with_deviation("'patience' diff is not implemented and can default to 'histogram' if lenient config is used, and defaults to histogram if unset for fastest and best results");
+ /// The `diff.renameLimit` key.
+ pub const RENAME_LIMIT: keys::UnsignedInteger = keys::UnsignedInteger::new_unsigned_integer(
+ "renameLimit",
+ &config::Tree::DIFF,
+ )
+ .with_note(
+ "The limit is actually squared, so 1000 stands for up to 1 million diffs if fuzzy rename tracking is enabled",
+ );
+ /// The `diff.renames` key.
+ pub const RENAMES: Renames = Renames::new_renames("renames", &config::Tree::DIFF);
+}
+
+impl Section for Diff {
+ fn name(&self) -> &str {
+ "diff"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::ALGORITHM, &Self::RENAME_LIMIT, &Self::RENAMES]
+ }
+}
+
+/// The `diff.algorithm` key.
+pub type Algorithm = keys::Any<validate::Algorithm>;
+
+/// The `diff.renames` key.
+pub type Renames = keys::Any<validate::Renames>;
+
+mod algorithm {
+ use std::borrow::Cow;
+
+ use crate::{
+ bstr::BStr,
+ config,
+ config::{diff::algorithm::Error, tree::sections::diff::Algorithm},
+ };
+
+ impl Algorithm {
+ /// Derive the diff algorithm identified by `name`, case-insensitively.
+ pub fn try_into_algorithm(&self, name: Cow<'_, BStr>) -> Result<gix_diff::blob::Algorithm, Error> {
+ let algo = if name.eq_ignore_ascii_case(b"myers") || name.eq_ignore_ascii_case(b"default") {
+ gix_diff::blob::Algorithm::Myers
+ } else if name.eq_ignore_ascii_case(b"minimal") {
+ gix_diff::blob::Algorithm::MyersMinimal
+ } else if name.eq_ignore_ascii_case(b"histogram") {
+ gix_diff::blob::Algorithm::Histogram
+ } else if name.eq_ignore_ascii_case(b"patience") {
+ return Err(config::diff::algorithm::Error::Unimplemented {
+ name: name.into_owned(),
+ });
+ } else {
+ return Err(Error::Unknown {
+ name: name.into_owned(),
+ });
+ };
+ Ok(algo)
+ }
+ }
+}
+
+mod renames {
+ use std::borrow::Cow;
+
+ use crate::{
+ bstr::{BStr, ByteSlice},
+ config::{
+ key::GenericError,
+ tree::{keys, sections::diff::Renames, Section},
+ },
+ diff::rename::Tracking,
+ };
+
+ impl Renames {
+ /// Create a new instance.
+ pub const fn new_renames(name: &'static str, section: &'static dyn Section) -> Self {
+ keys::Any::new_with_validate(name, section, super::validate::Renames)
+ }
+ /// Try to convert the configuration into a valid rename tracking variant. Use `value` and if it's an error, call `value_string`
+ /// to try and interpret the key as string.
+ pub fn try_into_renames<'a>(
+ &'static self,
+ value: Result<bool, gix_config::value::Error>,
+ value_string: impl FnOnce() -> Option<Cow<'a, BStr>>,
+ ) -> Result<Tracking, GenericError> {
+ Ok(match value {
+ Ok(true) => Tracking::Renames,
+ Ok(false) => Tracking::Disabled,
+ Err(err) => {
+ let value = value_string().ok_or_else(|| GenericError::from(self))?;
+ match value.as_ref().as_bytes() {
+ b"copy" | b"copies" => Tracking::RenamesAndCopies,
+ _ => return Err(GenericError::from_value(self, value.into_owned()).with_source(err)),
+ }
+ }
+ })
+ }
+ }
+}
+
+mod validate {
+ use std::borrow::Cow;
+
+ use crate::{
+ bstr::BStr,
+ config::tree::{keys, Diff},
+ };
+
+ pub struct Algorithm;
+ impl keys::Validate for Algorithm {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ Diff::ALGORITHM.try_into_algorithm(value.into())?;
+ Ok(())
+ }
+ }
+
+ pub struct Renames;
+ impl keys::Validate for Renames {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ let boolean = gix_config::Boolean::try_from(value).map(|b| b.0);
+ Diff::RENAMES.try_into_renames(boolean, || Some(Cow::Borrowed(value)))?;
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/extensions.rs b/vendor/gix/src/config/tree/sections/extensions.rs
new file mode 100644
index 000000000..77130f804
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/extensions.rs
@@ -0,0 +1,59 @@
+use crate::{
+ config,
+ config::tree::{keys, Extensions, Key, Section},
+};
+
+impl Extensions {
+ /// The `extensions.worktreeConfig` key.
+ pub const WORKTREE_CONFIG: keys::Boolean = keys::Boolean::new_boolean("worktreeConfig", &config::Tree::EXTENSIONS);
+ /// The `extensions.objectFormat` key.
+ pub const OBJECT_FORMAT: ObjectFormat =
+ ObjectFormat::new_with_validate("objectFormat", &config::Tree::EXTENSIONS, validate::ObjectFormat).with_note(
+ "Support for SHA256 is prepared but not fully implemented yet. For now we abort when encountered",
+ );
+}
+
+/// The `core.checkStat` key.
+pub type ObjectFormat = keys::Any<validate::ObjectFormat>;
+
+mod object_format {
+ use std::borrow::Cow;
+
+ use crate::{bstr::BStr, config, config::tree::sections::extensions::ObjectFormat};
+
+ impl ObjectFormat {
+ pub fn try_into_object_format(
+ &'static self,
+ value: Cow<'_, BStr>,
+ ) -> Result<gix_hash::Kind, config::key::GenericErrorWithValue> {
+ if value.as_ref().eq_ignore_ascii_case(b"sha1") {
+ Ok(gix_hash::Kind::Sha1)
+ } else {
+ Err(config::key::GenericErrorWithValue::from_value(self, value.into_owned()))
+ }
+ }
+ }
+}
+
+impl Section for Extensions {
+ fn name(&self) -> &str {
+ "extensions"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::OBJECT_FORMAT, &Self::WORKTREE_CONFIG]
+ }
+}
+
+mod validate {
+ use crate::{bstr::BStr, config::tree::keys};
+
+ pub struct ObjectFormat;
+
+ impl keys::Validate for ObjectFormat {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ super::Extensions::OBJECT_FORMAT.try_into_object_format(value.into())?;
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/gitoxide.rs b/vendor/gix/src/config/tree/sections/gitoxide.rs
new file mode 100644
index 000000000..8c3defd0b
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/gitoxide.rs
@@ -0,0 +1,363 @@
+use crate::config::tree::{keys, Gitoxide, Key, Section};
+
+impl Gitoxide {
+ /// The `gitoxide.allow` section.
+ pub const ALLOW: Allow = Allow;
+ /// The `gitoxide.author` section.
+ pub const AUTHOR: Author = Author;
+ /// The `gitoxide.commit` section.
+ pub const COMMIT: Commit = Commit;
+ /// The `gitoxide.committer` section.
+ pub const COMMITTER: Committer = Committer;
+ /// The `gitoxide.http` section.
+ pub const HTTP: Http = Http;
+ /// The `gitoxide.https` section.
+ pub const HTTPS: Https = Https;
+ /// The `gitoxide.objects` section.
+ pub const OBJECTS: Objects = Objects;
+ /// The `gitoxide.ssh` section.
+ pub const SSH: Ssh = Ssh;
+ /// The `gitoxide.user` section.
+ pub const USER: User = User;
+
+ /// The `gitoxide.userAgent` Key.
+ 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",
+ );
+}
+
+impl Section for Gitoxide {
+ fn name(&self) -> &str {
+ "gitoxide"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::USER_AGENT]
+ }
+
+ fn sub_sections(&self) -> &[&dyn Section] {
+ &[
+ &Self::ALLOW,
+ &Self::AUTHOR,
+ &Self::COMMIT,
+ &Self::COMMITTER,
+ &Self::HTTP,
+ &Self::HTTPS,
+ &Self::OBJECTS,
+ &Self::SSH,
+ &Self::USER,
+ ]
+ }
+}
+
+mod subsections {
+ use crate::config::{
+ tree::{http, keys, Gitoxide, Key, Section},
+ Tree,
+ };
+
+ /// The `Http` sub-section.
+ #[derive(Copy, Clone, Default)]
+ pub struct Http;
+
+ impl Http {
+ /// The `gitoxide.http.proxy` key.
+ pub const PROXY: keys::String =
+ keys::String::new_string("proxy", &Gitoxide::HTTP).with_environment_override("http_proxy");
+ /// The `gitoxide.http.allProxy` key.
+ pub const ALL_PROXY: keys::String = keys::String::new_string("allProxy", &Gitoxide::HTTP)
+ .with_environment_override("all_proxy")
+ .with_note("fallback environment is `ALL_PROXY`");
+ /// The `gitoxide.http.verbose` key.
+ ///
+ /// If set, curl will be configured to log verbosely.
+ pub const VERBOSE: keys::Boolean = keys::Boolean::new_boolean("verbose", &Gitoxide::HTTP)
+ .with_environment_override("GIT_CURL_VERBOSE")
+ .with_deviation("we parse it as boolean for convenience (infallible) but git only checks the presence");
+ /// The `gitoxide.http.noProxy` key.
+ pub const NO_PROXY: keys::String = keys::String::new_string("noProxy", &Gitoxide::HTTP)
+ .with_environment_override("no_proxy")
+ .with_note("fallback environment is `NO_PROXY`");
+ /// The `gitoxide.http.connectTimeout` key.
+ pub const CONNECT_TIMEOUT: keys::DurationInMilliseconds =
+ keys::DurationInMilliseconds::new_duration("connectTimeout", &Gitoxide::HTTP).with_note(
+ "entirely new, and in milliseconds, to describe how long to wait until a connection attempt is aborted",
+ );
+ /// The `gitoxide.http.sslVersionMin` key.
+ pub const SSL_VERSION_MIN: http::SslVersion =
+ http::SslVersion::new_ssl_version("sslVersionMin", &Gitoxide::HTTP).with_note(
+ "entirely new to set the lower bound for the allowed ssl version range. Overwrites the min bound of `http.sslVersion` if set. Min and Max must be set to become effective.",
+ );
+ /// The `gitoxide.http.sslVersionMax` key.
+ pub const SSL_VERSION_MAX: http::SslVersion =
+ 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.proxyAuthMethod` key.
+ pub const PROXY_AUTH_METHOD: http::ProxyAuthMethod =
+ http::ProxyAuthMethod::new_proxy_auth_method("proxyAuthMethod", &Gitoxide::HTTP)
+ .with_environment_override("GIT_HTTP_PROXY_AUTHMETHOD");
+ }
+
+ impl Section for Http {
+ fn name(&self) -> &str {
+ "http"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[
+ &Self::PROXY,
+ &Self::ALL_PROXY,
+ &Self::VERBOSE,
+ &Self::NO_PROXY,
+ &Self::CONNECT_TIMEOUT,
+ &Self::SSL_VERSION_MIN,
+ &Self::SSL_VERSION_MAX,
+ &Self::PROXY_AUTH_METHOD,
+ ]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&Tree::GITOXIDE)
+ }
+ }
+
+ /// The `Https` sub-section.
+ #[derive(Copy, Clone, Default)]
+ pub struct Https;
+
+ impl Https {
+ /// The `gitoxide.https.proxy` key.
+ pub const PROXY: keys::String = keys::String::new_string("proxy", &Gitoxide::HTTPS)
+ .with_environment_override("HTTPS_PROXY")
+ .with_note("fallback environment variable is `https_proxy`");
+ }
+
+ impl Section for Https {
+ fn name(&self) -> &str {
+ "https"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::PROXY]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&Tree::GITOXIDE)
+ }
+ }
+
+ /// The `allow` sub-section.
+ #[derive(Copy, Clone, Default)]
+ pub struct Allow;
+
+ /// The `gitoxide.allow.protocolFromUser` key.
+ pub type ProtocolFromUser = keys::Any<super::validate::ProtocolFromUser>;
+
+ impl Allow {
+ /// The `gitoxide.allow.protocolFromUser` key.
+ pub const PROTOCOL_FROM_USER: ProtocolFromUser = ProtocolFromUser::new_with_validate(
+ "protocolFromUser",
+ &Gitoxide::ALLOW,
+ super::validate::ProtocolFromUser,
+ )
+ .with_environment_override("GIT_PROTOCOL_FROM_USER");
+ }
+
+ impl Section for Allow {
+ fn name(&self) -> &str {
+ "allow"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::PROTOCOL_FROM_USER]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&Tree::GITOXIDE)
+ }
+ }
+
+ /// The `author` sub-section.
+ #[derive(Copy, Clone, Default)]
+ pub struct Author;
+
+ impl Author {
+ /// The `gitoxide.author.nameFallback` key.
+ pub const NAME_FALLBACK: keys::Any =
+ keys::Any::new("nameFallback", &Gitoxide::AUTHOR).with_environment_override("GIT_AUTHOR_NAME");
+ /// The `gitoxide.author.emailFallback` key.
+ pub const EMAIL_FALLBACK: keys::Any =
+ keys::Any::new("emailFallback", &Gitoxide::AUTHOR).with_environment_override("GIT_AUTHOR_EMAIL");
+ }
+
+ impl Section for Author {
+ fn name(&self) -> &str {
+ "author"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::NAME_FALLBACK, &Self::EMAIL_FALLBACK]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&Tree::GITOXIDE)
+ }
+ }
+
+ /// The `user` sub-section.
+ #[derive(Copy, Clone, Default)]
+ pub struct User;
+
+ impl User {
+ /// The `gitoxide.user.emailFallback` key.
+ pub const EMAIL_FALLBACK: keys::Any =
+ keys::Any::new("emailFallback", &Gitoxide::USER).with_environment_override("EMAIL");
+ }
+
+ impl Section for User {
+ fn name(&self) -> &str {
+ "user"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::EMAIL_FALLBACK]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&Tree::GITOXIDE)
+ }
+ }
+
+ /// The `ssh` sub-section.
+ #[derive(Copy, Clone, Default)]
+ pub struct Ssh;
+
+ impl Ssh {
+ /// The `gitoxide.ssh.commandWithoutShellFallback` key.
+ pub const COMMAND_WITHOUT_SHELL_FALLBACK: keys::Executable =
+ keys::Executable::new_executable("commandWithoutShellFallback", &Gitoxide::SSH)
+ .with_environment_override("GIT_SSH")
+ .with_note("is always executed without shell and treated as fallback");
+ }
+
+ impl Section for Ssh {
+ fn name(&self) -> &str {
+ "ssh"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::COMMAND_WITHOUT_SHELL_FALLBACK]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&Tree::GITOXIDE)
+ }
+ }
+
+ /// The `objects` sub-section.
+ #[derive(Copy, Clone, Default)]
+ pub struct Objects;
+
+ impl Objects {
+ /// The `gitoxide.objects.cacheLimit` key.
+ 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");
+ /// The `gitoxide.objects.noReplace` key.
+ pub const NO_REPLACE: keys::Boolean = keys::Boolean::new_boolean("noReplace", &Gitoxide::OBJECTS)
+ .with_environment_override("GIT_NO_REPLACE_OBJECTS");
+ /// The `gitoxide.objects.replaceRefBase` key.
+ pub const REPLACE_REF_BASE: keys::Any =
+ keys::Any::new("replaceRefBase", &Gitoxide::OBJECTS).with_environment_override("GIT_REPLACE_REF_BASE");
+ }
+
+ impl Section for Objects {
+ fn name(&self) -> &str {
+ "objects"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::CACHE_LIMIT, &Self::NO_REPLACE, &Self::REPLACE_REF_BASE]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&Tree::GITOXIDE)
+ }
+ }
+
+ /// The `committer` sub-section.
+ #[derive(Copy, Clone, Default)]
+ pub struct Committer;
+
+ impl Committer {
+ /// The `gitoxide.committer.nameFallback` key.
+ pub const NAME_FALLBACK: keys::Any =
+ keys::Any::new("nameFallback", &Gitoxide::COMMITTER).with_environment_override("GIT_COMMITTER_NAME");
+ /// The `gitoxide.committer.emailFallback` key.
+ pub const EMAIL_FALLBACK: keys::Any =
+ keys::Any::new("emailFallback", &Gitoxide::COMMITTER).with_environment_override("GIT_COMMITTER_EMAIL");
+ }
+
+ impl Section for Committer {
+ fn name(&self) -> &str {
+ "committer"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::NAME_FALLBACK, &Self::EMAIL_FALLBACK]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&Tree::GITOXIDE)
+ }
+ }
+
+ /// The `commit` sub-section.
+ #[derive(Copy, Clone, Default)]
+ pub struct Commit;
+
+ impl Commit {
+ /// The `gitoxide.commit.authorDate` key.
+ pub const AUTHOR_DATE: keys::Time =
+ keys::Time::new_time("authorDate", &Gitoxide::COMMIT).with_environment_override("GIT_AUTHOR_DATE");
+ /// The `gitoxide.commit.committerDate` key.
+ pub const COMMITTER_DATE: keys::Time =
+ keys::Time::new_time("committerDate", &Gitoxide::COMMIT).with_environment_override("GIT_COMMITTER_DATE");
+ }
+
+ impl Section for Commit {
+ fn name(&self) -> &str {
+ "commit"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&Tree::GITOXIDE)
+ }
+ }
+}
+
+pub mod validate {
+ use std::error::Error;
+
+ use crate::{bstr::BStr, config::tree::keys::Validate};
+
+ pub struct ProtocolFromUser;
+ impl Validate for ProtocolFromUser {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
+ if value != "1" {
+ return Err("GIT_PROTOCOL_FROM_USER is either unset or as the value '1'".into());
+ }
+ Ok(())
+ }
+ }
+}
+
+pub use subsections::{Allow, Author, Commit, Committer, Http, Https, Objects, Ssh, User};
+
+use crate::config;
diff --git a/vendor/gix/src/config/tree/sections/http.rs b/vendor/gix/src/config/tree/sections/http.rs
new file mode 100644
index 000000000..f45c37076
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/http.rs
@@ -0,0 +1,317 @@
+use crate::{
+ config,
+ config::tree::{keys, Http, Key, Section},
+};
+
+impl Http {
+ /// The `http.sslVersion` key.
+ pub const SSL_VERSION: SslVersion = SslVersion::new_ssl_version("sslVersion", &config::Tree::HTTP)
+ .with_environment_override("GIT_SSL_VERSION")
+ .with_deviation(
+ "accepts the new 'default' value which means to use the curl default just like the empty string does",
+ );
+ /// 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");
+ /// The `http.proxyAuthMethod` key.
+ pub const PROXY_AUTH_METHOD: ProxyAuthMethod =
+ ProxyAuthMethod::new_proxy_auth_method("proxyAuthMethod", &config::Tree::HTTP)
+ .with_deviation("implemented like git, but never actually tried");
+ /// The `http.version` key.
+ pub const VERSION: Version = Version::new_with_validate("version", &config::Tree::HTTP, validate::Version)
+ .with_deviation("fails on illformed UTF-8");
+ /// The `http.userAgent` key.
+ pub const USER_AGENT: keys::String =
+ keys::String::new_string("userAgent", &config::Tree::HTTP).with_deviation("fails on illformed UTF-8");
+ /// The `http.extraHeader` key.
+ pub const EXTRA_HEADER: ExtraHeader =
+ ExtraHeader::new_with_validate("extraHeader", &config::Tree::HTTP, validate::ExtraHeader)
+ .with_deviation("fails on illformed UTF-8, without leniency");
+ /// The `http.followRedirects` key.
+ pub const FOLLOW_REDIRECTS: FollowRedirects =
+ FollowRedirects::new_with_validate("followRedirects", &config::Tree::HTTP, validate::FollowRedirects);
+ /// The `http.lowSpeedTime` key.
+ pub const LOW_SPEED_TIME: keys::UnsignedInteger =
+ keys::UnsignedInteger::new_unsigned_integer("lowSpeedTime", &config::Tree::HTTP)
+ .with_deviation("fails on negative values");
+ /// The `http.lowSpeedLimit` key.
+ pub const LOW_SPEED_LIMIT: keys::UnsignedInteger =
+ keys::UnsignedInteger::new_unsigned_integer("lowSpeedLimit", &config::Tree::HTTP)
+ .with_deviation("fails on negative values");
+ /// The `http.schannelUseSSLCAInfo` key.
+ pub const SCHANNEL_USE_SSL_CA_INFO: keys::Boolean =
+ keys::Boolean::new_boolean("schannelUseSSLCAInfo", &config::Tree::HTTP)
+ .with_deviation("only used as switch internally to turn off using the sslCAInfo, unconditionally. If unset, it has no effect, whereas in `git` it defaults to false.");
+ /// The `http.sslCAInfo` key.
+ pub const SSL_CA_INFO: keys::Path =
+ keys::Path::new_path("sslCAInfo", &config::Tree::HTTP).with_environment_override("GIT_SSL_CAINFO");
+ /// The `http.schannelCheckRevoke` key.
+ pub const SCHANNEL_CHECK_REVOKE: keys::Boolean =
+ keys::Boolean::new_boolean("schannelCheckRevoke", &config::Tree::HTTP);
+}
+
+impl Section for Http {
+ fn name(&self) -> &str {
+ "http"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[
+ &Self::SSL_VERSION,
+ &Self::PROXY,
+ &Self::PROXY_AUTH_METHOD,
+ &Self::VERSION,
+ &Self::USER_AGENT,
+ &Self::EXTRA_HEADER,
+ &Self::FOLLOW_REDIRECTS,
+ &Self::LOW_SPEED_TIME,
+ &Self::LOW_SPEED_LIMIT,
+ &Self::SCHANNEL_USE_SSL_CA_INFO,
+ &Self::SSL_CA_INFO,
+ &Self::SCHANNEL_CHECK_REVOKE,
+ ]
+ }
+}
+
+/// The `http.followRedirects` key.
+pub type FollowRedirects = keys::Any<validate::FollowRedirects>;
+
+/// The `http.extraHeader` key.
+pub type ExtraHeader = keys::Any<validate::ExtraHeader>;
+
+/// The `http.sslVersion` key, as well as others of the same type.
+pub type SslVersion = keys::Any<validate::SslVersion>;
+
+/// The `http.proxyAuthMethod` key, as well as others of the same type.
+pub type ProxyAuthMethod = keys::Any<validate::ProxyAuthMethod>;
+
+/// The `http.version` key.
+pub type Version = keys::Any<validate::Version>;
+
+mod key_impls {
+ use crate::config::tree::{
+ http::{ProxyAuthMethod, SslVersion},
+ keys, Section,
+ };
+
+ impl SslVersion {
+ pub const fn new_ssl_version(name: &'static str, section: &'static dyn Section) -> Self {
+ keys::Any::new_with_validate(name, section, super::validate::SslVersion)
+ }
+ }
+
+ impl ProxyAuthMethod {
+ pub const fn new_proxy_auth_method(name: &'static str, section: &'static dyn Section) -> Self {
+ keys::Any::new_with_validate(name, section, super::validate::ProxyAuthMethod)
+ }
+ }
+
+ #[cfg(any(
+ feature = "blocking-http-transport-reqwest",
+ feature = "blocking-http-transport-curl"
+ ))]
+ impl crate::config::tree::http::FollowRedirects {
+ /// Convert `value` into the redirect specification, or query the same value as `boolean`
+ /// for additional possible input values.
+ ///
+ /// Note that `boolean` only queries the underlying key as boolean, which is a necessity to handle
+ /// empty booleans correctly, that is those without a value separator.
+ pub fn try_into_follow_redirects(
+ &'static self,
+ value: std::borrow::Cow<'_, crate::bstr::BStr>,
+ boolean: impl FnOnce() -> Result<Option<bool>, gix_config::value::Error>,
+ ) -> Result<
+ crate::protocol::transport::client::http::options::FollowRedirects,
+ crate::config::key::GenericErrorWithValue,
+ > {
+ use crate::{bstr::ByteSlice, protocol::transport::client::http::options::FollowRedirects};
+ Ok(if value.as_ref().as_bytes() == b"initial" {
+ FollowRedirects::Initial
+ } else if let Some(value) = boolean().map_err(|err| {
+ crate::config::key::GenericErrorWithValue::from_value(self, value.into_owned()).with_source(err)
+ })? {
+ if value {
+ FollowRedirects::All
+ } else {
+ FollowRedirects::None
+ }
+ } else {
+ FollowRedirects::Initial
+ })
+ }
+ }
+
+ impl super::ExtraHeader {
+ /// Convert a list of values into extra-headers, while failing entirely on illformed UTF-8.
+ pub fn try_into_extra_header(
+ &'static self,
+ values: Vec<std::borrow::Cow<'_, crate::bstr::BStr>>,
+ ) -> Result<Vec<String>, crate::config::string::Error> {
+ let mut out = Vec::with_capacity(values.len());
+ for value in values {
+ if value.is_empty() {
+ out.clear();
+ } else {
+ out.push(self.try_into_string(value)?);
+ }
+ }
+ Ok(out)
+ }
+ }
+
+ #[cfg(any(
+ feature = "blocking-http-transport-reqwest",
+ feature = "blocking-http-transport-curl"
+ ))]
+ impl super::Version {
+ pub fn try_into_http_version(
+ &'static self,
+ value: std::borrow::Cow<'_, crate::bstr::BStr>,
+ ) -> Result<
+ gix_protocol::transport::client::http::options::HttpVersion,
+ crate::config::key::GenericErrorWithValue,
+ > {
+ use gix_protocol::transport::client::http::options::HttpVersion;
+
+ use crate::bstr::ByteSlice;
+ Ok(match value.as_ref().as_bytes() {
+ b"HTTP/1.1" => HttpVersion::V1_1,
+ b"HTTP/2" => HttpVersion::V2,
+ _ => {
+ return Err(crate::config::key::GenericErrorWithValue::from_value(
+ self,
+ value.into_owned(),
+ ))
+ }
+ })
+ }
+ }
+
+ #[cfg(any(
+ feature = "blocking-http-transport-reqwest",
+ feature = "blocking-http-transport-curl"
+ ))]
+ impl ProxyAuthMethod {
+ pub fn try_into_proxy_auth_method(
+ &'static self,
+ value: std::borrow::Cow<'_, crate::bstr::BStr>,
+ ) -> Result<
+ gix_protocol::transport::client::http::options::ProxyAuthMethod,
+ crate::config::key::GenericErrorWithValue,
+ > {
+ use gix_protocol::transport::client::http::options::ProxyAuthMethod;
+
+ use crate::bstr::ByteSlice;
+ Ok(match value.as_ref().as_bytes() {
+ b"anyauth" => ProxyAuthMethod::AnyAuth,
+ b"basic" => ProxyAuthMethod::Basic,
+ b"digest" => ProxyAuthMethod::Digest,
+ b"negotiate" => ProxyAuthMethod::Negotiate,
+ b"ntlm" => ProxyAuthMethod::Ntlm,
+ _ => {
+ return Err(crate::config::key::GenericErrorWithValue::from_value(
+ self,
+ value.into_owned(),
+ ))
+ }
+ })
+ }
+ }
+
+ #[cfg(any(
+ feature = "blocking-http-transport-reqwest",
+ feature = "blocking-http-transport-curl"
+ ))]
+ impl SslVersion {
+ pub fn try_into_ssl_version(
+ &'static self,
+ value: std::borrow::Cow<'_, crate::bstr::BStr>,
+ ) -> Result<gix_protocol::transport::client::http::options::SslVersion, crate::config::ssl_version::Error>
+ {
+ use gix_protocol::transport::client::http::options::SslVersion::*;
+
+ use crate::bstr::ByteSlice;
+ Ok(match value.as_ref().as_bytes() {
+ b"default" | b"" => Default,
+ b"tlsv1" => TlsV1,
+ b"sslv2" => SslV2,
+ b"sslv3" => SslV3,
+ b"tlsv1.0" => TlsV1_0,
+ b"tlsv1.1" => TlsV1_1,
+ b"tlsv1.2" => TlsV1_2,
+ b"tlsv1.3" => TlsV1_3,
+ _ => return Err(crate::config::ssl_version::Error::from_value(self, value.into_owned())),
+ })
+ }
+ }
+}
+
+pub mod validate {
+ use std::error::Error;
+
+ use crate::{
+ bstr::{BStr, ByteSlice},
+ config::tree::keys::Validate,
+ };
+
+ pub struct SslVersion;
+ impl Validate for SslVersion {
+ fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
+ #[cfg(any(
+ feature = "blocking-http-transport-reqwest",
+ feature = "blocking-http-transport-curl"
+ ))]
+ super::Http::SSL_VERSION.try_into_ssl_version(std::borrow::Cow::Borrowed(_value))?;
+
+ Ok(())
+ }
+ }
+
+ pub struct ProxyAuthMethod;
+ impl Validate for ProxyAuthMethod {
+ fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
+ #[cfg(any(
+ feature = "blocking-http-transport-reqwest",
+ feature = "blocking-http-transport-curl"
+ ))]
+ super::Http::PROXY_AUTH_METHOD.try_into_proxy_auth_method(std::borrow::Cow::Borrowed(_value))?;
+
+ Ok(())
+ }
+ }
+
+ pub struct Version;
+ impl Validate for Version {
+ fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
+ #[cfg(any(
+ feature = "blocking-http-transport-reqwest",
+ feature = "blocking-http-transport-curl"
+ ))]
+ super::Http::VERSION.try_into_http_version(std::borrow::Cow::Borrowed(_value))?;
+
+ Ok(())
+ }
+ }
+
+ pub struct ExtraHeader;
+ impl Validate for ExtraHeader {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
+ value.to_str()?;
+ Ok(())
+ }
+ }
+
+ pub struct FollowRedirects;
+ impl Validate for FollowRedirects {
+ fn validate(&self, _value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
+ #[cfg(any(
+ feature = "blocking-http-transport-reqwest",
+ feature = "blocking-http-transport-curl"
+ ))]
+ super::Http::FOLLOW_REDIRECTS.try_into_follow_redirects(std::borrow::Cow::Borrowed(_value), || {
+ gix_config::Boolean::try_from(_value).map(|b| Some(b.0))
+ })?;
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/init.rs b/vendor/gix/src/config/tree/sections/init.rs
new file mode 100644
index 000000000..de42d3b62
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/init.rs
@@ -0,0 +1,20 @@
+use crate::{
+ config,
+ config::tree::{keys, Init, Key, Section},
+};
+
+impl Init {
+ /// The `init.defaultBranch` key.
+ pub const DEFAULT_BRANCH: keys::Any = keys::Any::new("defaultBranch", &config::Tree::INIT)
+ .with_deviation("If not set, we use `main` instead of `master`");
+}
+
+impl Section for Init {
+ fn name(&self) -> &str {
+ "init"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::DEFAULT_BRANCH]
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/mod.rs b/vendor/gix/src/config/tree/sections/mod.rs
new file mode 100644
index 000000000..fb9b50786
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/mod.rs
@@ -0,0 +1,96 @@
+#![allow(missing_docs)]
+
+/// The `author` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Author;
+mod author;
+
+/// The `branch` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Branch;
+pub mod branch;
+
+/// The `checkout` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Checkout;
+pub mod checkout;
+
+/// The `clone` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Clone;
+mod clone;
+
+/// The `committer` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Committer;
+mod committer;
+
+/// The `core` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Core;
+pub mod core;
+
+/// The `credential` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Credential;
+pub mod credential;
+
+/// The `diff` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Diff;
+pub mod diff;
+
+/// The `extension` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Extensions;
+pub mod extensions;
+
+/// The `gitoxide` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Gitoxide;
+pub mod gitoxide;
+
+/// The `http` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Http;
+pub mod http;
+
+/// The `init` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Init;
+mod init;
+
+/// The `pack` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Pack;
+pub mod pack;
+
+/// The `protocol` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Protocol;
+pub mod protocol;
+
+/// The `remote` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Remote;
+pub mod remote;
+
+/// The `safe` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Safe;
+mod safe;
+
+/// The `ssh` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Ssh;
+pub mod ssh;
+
+/// The `user` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct User;
+mod user;
+
+/// The `url` top-level section.
+#[derive(Copy, Clone, Default)]
+pub struct Url;
+mod url;
diff --git a/vendor/gix/src/config/tree/sections/pack.rs b/vendor/gix/src/config/tree/sections/pack.rs
new file mode 100644
index 000000000..941817e5b
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/pack.rs
@@ -0,0 +1,64 @@
+use crate::{
+ config,
+ config::tree::{keys, Key, Pack, Section},
+};
+
+impl Pack {
+ /// The `pack.threads` key.
+ pub const THREADS: keys::UnsignedInteger =
+ keys::UnsignedInteger::new_unsigned_integer("threads", &config::Tree::PACK)
+ .with_deviation("Leaving this key unspecified uses all available cores, instead of 1");
+
+ /// The `pack.indexVersion` key.
+ pub const INDEX_VERSION: IndexVersion =
+ IndexVersion::new_with_validate("indexVersion", &config::Tree::PACK, validate::IndexVersion);
+}
+
+/// The `pack.indexVersion` key.
+pub type IndexVersion = keys::Any<validate::IndexVersion>;
+
+mod index_version {
+ use crate::{config, config::tree::sections::pack::IndexVersion};
+
+ impl IndexVersion {
+ /// Try to interpret an integer value as index version.
+ pub fn try_into_index_version(
+ &'static self,
+ value: Result<i64, gix_config::value::Error>,
+ ) -> Result<gix_pack::index::Version, config::key::GenericError> {
+ let value = value.map_err(|err| config::key::GenericError::from(self).with_source(err))?;
+ Ok(match value {
+ 1 => gix_pack::index::Version::V1,
+ 2 => gix_pack::index::Version::V2,
+ _ => return Err(config::key::GenericError::from(self)),
+ })
+ }
+ }
+}
+
+impl Section for Pack {
+ fn name(&self) -> &str {
+ "pack"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::THREADS, &Self::INDEX_VERSION]
+ }
+}
+
+mod validate {
+ use crate::{bstr::BStr, config::tree::keys};
+
+ pub struct IndexVersion;
+ impl keys::Validate for IndexVersion {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ super::Pack::INDEX_VERSION.try_into_index_version(gix_config::Integer::try_from(value).and_then(
+ |int| {
+ int.to_decimal()
+ .ok_or_else(|| gix_config::value::Error::new("integer out of range", value))
+ },
+ ))?;
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/protocol.rs b/vendor/gix/src/config/tree/sections/protocol.rs
new file mode 100644
index 000000000..58e907b0f
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/protocol.rs
@@ -0,0 +1,85 @@
+use crate::{
+ config,
+ config::tree::{keys, Key, Protocol, Section},
+};
+
+impl Protocol {
+ /// The `protocol.allow` key.
+ pub const ALLOW: Allow = Allow::new_with_validate("allow", &config::Tree::PROTOCOL, validate::Allow);
+
+ /// The `protocol.<name>` subsection
+ pub const NAME_PARAMETER: NameParameter = NameParameter;
+}
+
+/// The `protocol.allow` key type.
+pub type Allow = keys::Any<validate::Allow>;
+
+#[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
+mod allow {
+ use std::borrow::Cow;
+
+ use crate::{bstr::BStr, config, config::tree::protocol::Allow, remote::url::scheme_permission};
+
+ impl Allow {
+ /// Convert `value` into its respective `Allow` variant, possibly informing about the `scheme` we are looking at in the error.
+ pub fn try_into_allow(
+ &'static self,
+ value: Cow<'_, BStr>,
+ scheme: Option<&str>,
+ ) -> Result<scheme_permission::Allow, config::protocol::allow::Error> {
+ scheme_permission::Allow::try_from(value).map_err(|value| config::protocol::allow::Error {
+ value,
+ scheme: scheme.map(ToOwned::to_owned),
+ })
+ }
+ }
+}
+
+/// The `protocol.<name>` parameter section.
+pub struct NameParameter;
+
+impl NameParameter {
+ /// The `credential.<url>.helper` key.
+ pub const ALLOW: Allow = Allow::new_with_validate("allow", &Protocol::NAME_PARAMETER, validate::Allow);
+}
+
+impl Section for NameParameter {
+ fn name(&self) -> &str {
+ "<name>"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::ALLOW]
+ }
+
+ fn parent(&self) -> Option<&dyn Section> {
+ Some(&config::Tree::PROTOCOL)
+ }
+}
+
+impl Section for Protocol {
+ fn name(&self) -> &str {
+ "protocol"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::ALLOW]
+ }
+
+ fn sub_sections(&self) -> &[&dyn Section] {
+ &[&Self::NAME_PARAMETER]
+ }
+}
+
+mod validate {
+ use crate::{bstr::BStr, config::tree::keys};
+
+ pub struct Allow;
+ impl keys::Validate for Allow {
+ fn validate(&self, _value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ #[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
+ super::Protocol::ALLOW.try_into_allow(std::borrow::Cow::Borrowed(_value), None)?;
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/remote.rs b/vendor/gix/src/config/tree/sections/remote.rs
new file mode 100644
index 000000000..b242c9c14
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/remote.rs
@@ -0,0 +1,101 @@
+use crate::{
+ config,
+ config::tree::{http, keys, Key, Remote, Section, SubSectionRequirement},
+};
+
+const NAME_PARAMETER: Option<SubSectionRequirement> = Some(SubSectionRequirement::Parameter("name"));
+
+impl Remote {
+ /// The `remote.pushDefault` key
+ pub const PUSH_DEFAULT: keys::RemoteName = keys::RemoteName::new_remote_name("pushDefault", &config::Tree::REMOTE);
+ /// The `remote.<name>.tagOpt` key
+ pub const TAG_OPT: TagOpt = TagOpt::new_with_validate("tagOpt", &config::Tree::REMOTE, validate::TagOpt)
+ .with_subsection_requirement(Some(SubSectionRequirement::Parameter("name")));
+ /// The `remote.<name>.url` key
+ pub const URL: keys::Url =
+ keys::Url::new_url("url", &config::Tree::REMOTE).with_subsection_requirement(NAME_PARAMETER);
+ /// The `remote.<name>.pushUrl` key
+ pub const PUSH_URL: keys::Url =
+ keys::Url::new_url("pushUrl", &config::Tree::REMOTE).with_subsection_requirement(NAME_PARAMETER);
+ /// The `remote.<name>.fetch` key
+ pub const FETCH: keys::FetchRefSpec = keys::FetchRefSpec::new_fetch_refspec("fetch", &config::Tree::REMOTE)
+ .with_subsection_requirement(NAME_PARAMETER);
+ /// The `remote.<name>.push` key
+ pub const PUSH: keys::PushRefSpec =
+ keys::PushRefSpec::new_push_refspec("push", &config::Tree::REMOTE).with_subsection_requirement(NAME_PARAMETER);
+ /// The `remote.<name>.proxy` key
+ pub const PROXY: keys::String =
+ keys::String::new_string("proxy", &config::Tree::REMOTE).with_subsection_requirement(NAME_PARAMETER);
+ /// The `remote.<name>.proxyAuthMethod` key.
+ pub const PROXY_AUTH_METHOD: http::ProxyAuthMethod =
+ http::ProxyAuthMethod::new_proxy_auth_method("proxyAuthMethod", &config::Tree::REMOTE)
+ .with_subsection_requirement(NAME_PARAMETER)
+ .with_deviation("implemented like git, but never actually tried");
+}
+
+impl Section for Remote {
+ fn name(&self) -> &str {
+ "remote"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[
+ &Self::PUSH_DEFAULT,
+ &Self::TAG_OPT,
+ &Self::URL,
+ &Self::PUSH_URL,
+ &Self::FETCH,
+ &Self::PUSH,
+ &Self::PROXY,
+ &Self::PROXY_AUTH_METHOD,
+ ]
+ }
+}
+
+/// The `remote.<name>.tagOpt` key type.
+pub type TagOpt = keys::Any<validate::TagOpt>;
+
+mod tag_opts {
+ use std::borrow::Cow;
+
+ use crate::{
+ bstr::{BStr, ByteSlice},
+ config,
+ config::tree::remote::TagOpt,
+ remote,
+ };
+
+ impl TagOpt {
+ /// Try to interpret `value` as tag option.
+ ///
+ /// # Note
+ ///
+ /// It's heavily biased towards the git command-line unfortunately, and the only
+ /// value of its kind. Maybe in future more values will be supported which are less
+ /// about passing them to a sub-process.
+ pub fn try_into_tag_opt(
+ &'static self,
+ value: Cow<'_, BStr>,
+ ) -> Result<remote::fetch::Tags, config::key::GenericErrorWithValue> {
+ Ok(match value.as_ref().as_bytes() {
+ b"--tags" => remote::fetch::Tags::All,
+ b"--no-tags" => remote::fetch::Tags::None,
+ _ => return Err(config::key::GenericErrorWithValue::from_value(self, value.into_owned())),
+ })
+ }
+ }
+}
+
+pub mod validate {
+ use std::{borrow::Cow, error::Error};
+
+ use crate::{bstr::BStr, config::tree::keys::Validate};
+
+ pub struct TagOpt;
+ impl Validate for TagOpt {
+ fn validate(&self, value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
+ super::Remote::TAG_OPT.try_into_tag_opt(Cow::Borrowed(value))?;
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/safe.rs b/vendor/gix/src/config/tree/sections/safe.rs
new file mode 100644
index 000000000..e76d28888
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/safe.rs
@@ -0,0 +1,27 @@
+use crate::{
+ config,
+ config::tree::{keys, Key, Safe, Section},
+};
+
+impl Safe {
+ /// The `safe.directory` key
+ pub const DIRECTORY: keys::Any = keys::Any::new("directory", &config::Tree::SAFE);
+}
+
+impl Safe {
+ /// Implements the directory filter to trust only global and system files, for use with `safe.directory`.
+ pub fn directory_filter(meta: &gix_config::file::Metadata) -> bool {
+ let kind = meta.source.kind();
+ kind == gix_config::source::Kind::System || kind == gix_config::source::Kind::Global
+ }
+}
+
+impl Section for Safe {
+ fn name(&self) -> &str {
+ "safe"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::DIRECTORY]
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/ssh.rs b/vendor/gix/src/config/tree/sections/ssh.rs
new file mode 100644
index 000000000..600ee663b
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/ssh.rs
@@ -0,0 +1,65 @@
+use crate::{
+ config,
+ config::tree::{keys, Key, Section, Ssh},
+};
+
+impl Ssh {
+ /// The `ssh.variant` key
+ pub const VARIANT: Variant = Variant::new_with_validate("variant", &config::Tree::SSH, validate::Variant)
+ .with_environment_override("GIT_SSH_VARIANT")
+ .with_deviation("We error if a variant is chosen that we don't know, as opposed to defaulting to 'ssh'");
+}
+
+/// The `ssh.variant` key.
+pub type Variant = keys::Any<validate::Variant>;
+
+#[cfg(feature = "blocking-network-client")]
+mod variant {
+ use std::borrow::Cow;
+
+ use crate::{bstr::BStr, config, config::tree::ssh::Variant};
+
+ impl Variant {
+ pub fn try_into_variant(
+ &'static self,
+ value: Cow<'_, BStr>,
+ ) -> Result<Option<gix_protocol::transport::client::ssh::ProgramKind>, config::key::GenericErrorWithValue>
+ {
+ use gix_protocol::transport::client::ssh::ProgramKind;
+
+ use crate::bstr::ByteSlice;
+ Ok(Some(match value.as_ref().as_bytes() {
+ b"auto" => return Ok(None),
+ b"ssh" => ProgramKind::Ssh,
+ b"plink" => ProgramKind::Plink,
+ b"putty" => ProgramKind::Putty,
+ b"tortoiseplink" => ProgramKind::TortoisePlink,
+ b"simple" => ProgramKind::Simple,
+ _ => return Err(config::key::GenericErrorWithValue::from_value(self, value.into_owned())),
+ }))
+ }
+ }
+}
+
+impl Section for Ssh {
+ fn name(&self) -> &str {
+ "ssh"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::VARIANT]
+ }
+}
+
+mod validate {
+ use crate::{bstr::BStr, config::tree::keys};
+
+ pub struct Variant;
+ impl keys::Validate for Variant {
+ fn validate(&self, _value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
+ #[cfg(feature = "blocking-network-client")]
+ super::Ssh::VARIANT.try_into_variant(_value.into())?;
+ Ok(())
+ }
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/url.rs b/vendor/gix/src/config/tree/sections/url.rs
new file mode 100644
index 000000000..6a9c0bfdb
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/url.rs
@@ -0,0 +1,25 @@
+use crate::{
+ config,
+ config::tree::{keys, Key, Section, SubSectionRequirement, Url},
+};
+
+const BASE_PARAMETER: Option<SubSectionRequirement> = Some(SubSectionRequirement::Parameter("base"));
+
+impl Url {
+ /// The `url.<base>.insteadOf` key
+ pub const INSTEAD_OF: keys::Any =
+ keys::Any::new("insteadOf", &config::Tree::URL).with_subsection_requirement(BASE_PARAMETER);
+ /// The `url.<base>.pushInsteadOf` key
+ pub const PUSH_INSTEAD_OF: keys::Any =
+ keys::Any::new("pushInsteadOf", &config::Tree::URL).with_subsection_requirement(BASE_PARAMETER);
+}
+
+impl Section for Url {
+ fn name(&self) -> &str {
+ "url"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::INSTEAD_OF, &Self::PUSH_INSTEAD_OF]
+ }
+}
diff --git a/vendor/gix/src/config/tree/sections/user.rs b/vendor/gix/src/config/tree/sections/user.rs
new file mode 100644
index 000000000..d1f4f7102
--- /dev/null
+++ b/vendor/gix/src/config/tree/sections/user.rs
@@ -0,0 +1,22 @@
+use crate::{
+ config,
+ config::tree::{gitoxide, keys, Key, Section, User},
+};
+
+impl User {
+ /// The `user.name` key
+ pub const NAME: keys::Any = keys::Any::new("name", &config::Tree::USER);
+ /// The `user.email` key
+ pub const EMAIL: keys::Any =
+ keys::Any::new("email", &config::Tree::USER).with_fallback(&gitoxide::User::EMAIL_FALLBACK);
+}
+
+impl Section for User {
+ fn name(&self) -> &str {
+ "user"
+ }
+
+ fn keys(&self) -> &[&dyn Key] {
+ &[&Self::NAME, &Self::EMAIL]
+ }
+}