Skip to content

Allow configuting the Repository object created by PrepareFetch #1141

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions gix/src/clone/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<BString>) -> Result<Self, crate::remote::name::Error> {
Expand All @@ -34,6 +34,14 @@ impl PrepareFetch {
self.shallow = shallow;
self
}

/// 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<Item = impl Into<BString>>) -> Self {
self.config_overrides = values.into_iter().map(Into::into).collect();
self
}
}

/// Consumption
Expand Down
10 changes: 10 additions & 0 deletions gix/src/clone/fetch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ pub enum Error {
RemoteConnection(#[source] Box<dyn std::error::Error + Send + Sync>),
#[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")]
Expand Down Expand Up @@ -75,6 +79,12 @@ impl PrepareFetch {
.as_mut()
.expect("user error: multiple calls are allowed only until it succeeds");

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(),
None => repo
Expand Down
7 changes: 5 additions & 2 deletions gix/src/clone/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub struct PrepareFetch {
repo: Option<crate::Repository>,
/// The name of the remote, which defaults to `origin` if not overridden.
remote_name: Option<BString>,
/// Additional config `values` that are applied in-memory before starting the fetch process.
config_overrides: Vec<BString>,
/// A function to configure a remote prior to fetching a pack.
configure_remote: Option<ConfigureRemoteFn>,
/// A function to configure a connection before using it.
Expand Down Expand Up @@ -126,6 +128,7 @@ impl PrepareFetch {
#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))]
fetch_options: Default::default(),
repo: Some(repo),
config_overrides: Vec::new(),
remote_name: None,
configure_remote: None,
#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))]
Expand All @@ -144,8 +147,6 @@ pub struct PrepareCheckout {
pub(self) repo: Option<crate::Repository>,
}

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"))]
Expand Down Expand Up @@ -181,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;
13 changes: 13 additions & 0 deletions gix/tests/clone/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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(())
}

Expand Down