From 9833b45c59ebb078b3f5c35fdb0a5b9bd3453fbc Mon Sep 17 00:00:00 2001 From: Bittrance Date: Fri, 8 Dec 2023 10:45:58 +0100 Subject: [PATCH 1/2] Allow overriding Git configuration when cloning. --- gix/src/clone/access.rs | 7 +++++++ gix/src/clone/fetch/mod.rs | 8 ++++++++ gix/src/clone/mod.rs | 3 +++ 3 files changed, 18 insertions(+) diff --git a/gix/src/clone/access.rs b/gix/src/clone/access.rs index 1c817e939ab..5d8be7d6852 100644 --- a/gix/src/clone/access.rs +++ b/gix/src/clone/access.rs @@ -34,6 +34,13 @@ impl PrepareFetch { self.shallow = shallow; self } + + /// Apply the given configuration `values` early to allow affecting the repository instantiation phase. + /// The configuration is marked with [source API][gix_config::Source::Api]. + pub fn config_overrides(mut self, values: impl IntoIterator>) -> Self { + self.api_config_overrides = values.into_iter().map(Into::into).collect(); + self + } } /// Consumption diff --git a/gix/src/clone/fetch/mod.rs b/gix/src/clone/fetch/mod.rs index 8f05b10e95b..045fcc9f5ba 100644 --- a/gix/src/clone/fetch/mod.rs +++ b/gix/src/clone/fetch/mod.rs @@ -18,6 +18,10 @@ pub enum Error { RemoteConnection(#[source] Box), #[error(transparent)] RemoteName(#[from] crate::config::remote::symbolic_name::Error), + #[error(transparent)] + ParseConfig(#[from] crate::config::overrides::Error), + #[error(transparent)] + ApplyConfig(#[from] crate::config::Error), #[error("Failed to load repo-local git configuration before writing")] LoadConfig(#[from] gix_config::file::init::from_paths::Error), #[error("Failed to store configured remote in memory")] @@ -75,6 +79,10 @@ impl PrepareFetch { .as_mut() .expect("user error: multiple calls are allowed only until it succeeds"); + let mut snapshot = repo.config_snapshot_mut(); + snapshot.append_config(self.api_config_overrides.as_slice(), gix_config::Source::Api)?; + snapshot.commit()?; + let remote_name = match self.remote_name.as_ref() { Some(name) => name.to_owned(), None => repo diff --git a/gix/src/clone/mod.rs b/gix/src/clone/mod.rs index 8afc3b99b28..bcddc26f46d 100644 --- a/gix/src/clone/mod.rs +++ b/gix/src/clone/mod.rs @@ -20,6 +20,8 @@ pub struct PrepareFetch { repo: Option, /// The name of the remote, which defaults to `origin` if not overridden. remote_name: Option, + /// Additional config `values` that are applied in-memory before starting the fetch process. + api_config_overrides: Vec, /// A function to configure a remote prior to fetching a pack. configure_remote: Option, /// A function to configure a connection before using it. @@ -126,6 +128,7 @@ impl PrepareFetch { #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] fetch_options: Default::default(), repo: Some(repo), + api_config_overrides: Vec::new(), remote_name: None, configure_remote: None, #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] From b5c36b805d0b269e6d87ca8b6c517b7fd7337622 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 8 Dec 2023 14:04:01 +0100 Subject: [PATCH 2/2] feat: add `clone::PrepareFetch::with_in_memory_config_overrides()`. With it one can affect the repository configuration right before fetching. --- gix/src/clone/access.rs | 13 +++++++------ gix/src/clone/fetch/mod.rs | 8 +++++--- gix/src/clone/mod.rs | 8 ++++---- gix/tests/clone/mod.rs | 13 +++++++++++++ 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/gix/src/clone/access.rs b/gix/src/clone/access.rs index 5d8be7d6852..966c54b6671 100644 --- a/gix/src/clone/access.rs +++ b/gix/src/clone/access.rs @@ -10,7 +10,7 @@ impl PrepareFetch { /// _all changes done in `f()` will be persisted_. /// /// It can also be used to configure additional options, like those for fetching tags. Note that - /// [`with_fetch_tags()`][crate::Remote::with_fetch_tags()] should be called here to configure the clone as desired. + /// [`with_fetch_tags()`](crate::Remote::with_fetch_tags()) should be called here to configure the clone as desired. /// Otherwise a clone is configured to be complete and fetches all tags, not only those reachable from all branches. pub fn configure_remote( mut self, @@ -21,7 +21,7 @@ impl PrepareFetch { } /// Set the remote's name to the given value after it was configured using the function provided via - /// [`configure_remote()`][Self::configure_remote()]. + /// [`configure_remote()`](Self::configure_remote()). /// /// If not set here, it defaults to `origin` or the value of `clone.defaultRemoteName`. pub fn with_remote_name(mut self, name: impl Into) -> Result { @@ -35,10 +35,11 @@ impl PrepareFetch { self } - /// Apply the given configuration `values` early to allow affecting the repository instantiation phase. - /// The configuration is marked with [source API][gix_config::Source::Api]. - pub fn config_overrides(mut self, values: impl IntoIterator>) -> Self { - self.api_config_overrides = values.into_iter().map(Into::into).collect(); + /// Apply the given configuration `values` right before readying the actual fetch from the remote. + /// The configuration is marked with [source API](gix_config::Source::Api), and will not be written back, it's + /// retained only in memory. + pub fn with_in_memory_config_overrides(mut self, values: impl IntoIterator>) -> Self { + self.config_overrides = values.into_iter().map(Into::into).collect(); self } } diff --git a/gix/src/clone/fetch/mod.rs b/gix/src/clone/fetch/mod.rs index 045fcc9f5ba..8fdee98edba 100644 --- a/gix/src/clone/fetch/mod.rs +++ b/gix/src/clone/fetch/mod.rs @@ -79,9 +79,11 @@ impl PrepareFetch { .as_mut() .expect("user error: multiple calls are allowed only until it succeeds"); - let mut snapshot = repo.config_snapshot_mut(); - snapshot.append_config(self.api_config_overrides.as_slice(), gix_config::Source::Api)?; - snapshot.commit()?; + if !self.config_overrides.is_empty() { + let mut snapshot = repo.config_snapshot_mut(); + snapshot.append_config(&self.config_overrides, gix_config::Source::Api)?; + snapshot.commit()?; + } let remote_name = match self.remote_name.as_ref() { Some(name) => name.to_owned(), diff --git a/gix/src/clone/mod.rs b/gix/src/clone/mod.rs index bcddc26f46d..9e401386226 100644 --- a/gix/src/clone/mod.rs +++ b/gix/src/clone/mod.rs @@ -21,7 +21,7 @@ pub struct PrepareFetch { /// The name of the remote, which defaults to `origin` if not overridden. remote_name: Option, /// Additional config `values` that are applied in-memory before starting the fetch process. - api_config_overrides: Vec, + config_overrides: Vec, /// A function to configure a remote prior to fetching a pack. configure_remote: Option, /// A function to configure a connection before using it. @@ -128,7 +128,7 @@ impl PrepareFetch { #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] fetch_options: Default::default(), repo: Some(repo), - api_config_overrides: Vec::new(), + config_overrides: Vec::new(), remote_name: None, configure_remote: None, #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] @@ -147,8 +147,6 @@ pub struct PrepareCheckout { pub(self) repo: Option, } -mod access; - // This module encapsulates functionality that works with both feature toggles. Can be combined with `fetch` // once async and clone are a thing. #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] @@ -184,6 +182,8 @@ mod access_feat { #[cfg(any(feature = "async-network-client-async-std", feature = "blocking-network-client"))] pub mod fetch; +mod access; + /// #[cfg(feature = "worktree-mutation")] pub mod checkout; diff --git a/gix/tests/clone/mod.rs b/gix/tests/clone/mod.rs index dc742058044..891199c78d2 100644 --- a/gix/tests/clone/mod.rs +++ b/gix/tests/clone/mod.rs @@ -109,6 +109,7 @@ mod blocking_io { fn from_shallow_allowed_by_default() -> crate::Result { let tmp = gix_testtools::tempfile::TempDir::new()?; let (repo, _change) = gix::prepare_clone_bare(remote::repo("base.shallow").path(), tmp.path())? + .with_in_memory_config_overrides(Some("my.marker=1")) .fetch_only(gix::progress::Discard, &std::sync::atomic::AtomicBool::default())?; assert_eq!( repo.shallow_commits()?.expect("present").as_slice(), @@ -118,6 +119,18 @@ mod blocking_io { hex_to_id("dfd0954dabef3b64f458321ef15571cc1a46d552"), ] ); + assert_eq!( + repo.config_snapshot().boolean("my.marker"), + Some(true), + "configuration overrides are set in time" + ); + assert_eq!( + gix::open_opts(repo.git_dir(), gix::open::Options::isolated())? + .config_snapshot() + .boolean("my.marker"), + None, + "these options are not persisted" + ); Ok(()) }