diff options
Diffstat (limited to 'vendor/gix/src/clone')
-rw-r--r-- | vendor/gix/src/clone/access.rs | 61 | ||||
-rw-r--r-- | vendor/gix/src/clone/checkout.rs | 9 | ||||
-rw-r--r-- | vendor/gix/src/clone/fetch/mod.rs | 85 | ||||
-rw-r--r-- | vendor/gix/src/clone/mod.rs | 53 |
4 files changed, 132 insertions, 76 deletions
diff --git a/vendor/gix/src/clone/access.rs b/vendor/gix/src/clone/access.rs new file mode 100644 index 000000000..5b6e5fbab --- /dev/null +++ b/vendor/gix/src/clone/access.rs @@ -0,0 +1,61 @@ +use crate::bstr::BString; +use crate::clone::PrepareFetch; +use crate::Repository; + +/// Builder +impl PrepareFetch { + /// Use `f` to apply arbitrary changes to the remote that is about to be used to fetch a pack. + /// + /// The passed in `remote` will be un-named and pre-configured to be a default remote as we know it from git-clone. + /// It is not yet present in the configuration of the repository, + /// but each change it will eventually be written to the configuration prior to performing a the fetch operation, + /// _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. + /// 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, + f: impl FnMut(crate::Remote<'_>) -> Result<crate::Remote<'_>, Box<dyn std::error::Error + Send + Sync>> + 'static, + ) -> Self { + self.configure_remote = Some(Box::new(f)); + self + } + + /// Set the remote's name to the given value after it was configured using the function provided via + /// [`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> { + self.remote_name = Some(crate::remote::name::validated(name)?); + Ok(self) + } + + /// Make this clone a shallow one with the respective choice of shallow-ness. + pub fn with_shallow(mut self, shallow: crate::remote::fetch::Shallow) -> Self { + self.shallow = shallow; + self + } +} + +/// Consumption +impl PrepareFetch { + /// Persist the contained repository as is even if an error may have occurred when fetching from the remote. + pub fn persist(mut self) -> Repository { + self.repo.take().expect("present and consumed once") + } +} + +impl Drop for PrepareFetch { + fn drop(&mut self) { + if let Some(repo) = self.repo.take() { + std::fs::remove_dir_all(repo.work_dir().unwrap_or_else(|| repo.path())).ok(); + } + } +} + +impl From<PrepareFetch> for Repository { + fn from(prep: PrepareFetch) -> Self { + prep.persist() + } +} diff --git a/vendor/gix/src/clone/checkout.rs b/vendor/gix/src/clone/checkout.rs index 50d235f13..823005551 100644 --- a/vendor/gix/src/clone/checkout.rs +++ b/vendor/gix/src/clone/checkout.rs @@ -27,8 +27,7 @@ pub mod main_worktree { CheckoutOptions(#[from] crate::config::checkout_options::Error), #[error(transparent)] IndexCheckout( - #[from] - gix_worktree::index::checkout::Error<gix_odb::find::existing_object::Error<gix_odb::store::find::Error>>, + #[from] gix_worktree::checkout::Error<gix_odb::find::existing_object::Error<gix_odb::store::find::Error>>, ), #[error("Failed to reopen object database as Arc (only if thread-safety wasn't compiled in)")] OpenArcOdb(#[from] std::io::Error), @@ -69,7 +68,7 @@ pub mod main_worktree { &mut self, mut progress: impl crate::Progress, should_interrupt: &AtomicBool, - ) -> Result<(Repository, gix_worktree::index::checkout::Outcome), Error> { + ) -> Result<(Repository, gix_worktree::checkout::Outcome), Error> { let repo = self .repo .as_ref() @@ -82,7 +81,7 @@ pub mod main_worktree { None => { return Ok(( self.repo.take().expect("still present"), - gix_worktree::index::checkout::Outcome::default(), + gix_worktree::checkout::Outcome::default(), )) } }; @@ -103,7 +102,7 @@ pub mod main_worktree { bytes.init(None, crate::progress::bytes()); let start = std::time::Instant::now(); - let outcome = gix_worktree::index::checkout( + let outcome = gix_worktree::checkout( &mut index, workdir, { diff --git a/vendor/gix/src/clone/fetch/mod.rs b/vendor/gix/src/clone/fetch/mod.rs index d663b47ea..59f820675 100644 --- a/vendor/gix/src/clone/fetch/mod.rs +++ b/vendor/gix/src/clone/fetch/mod.rs @@ -1,9 +1,8 @@ -use crate::{bstr::BString, clone::PrepareFetch, Repository}; +use crate::clone::PrepareFetch; /// The error returned by [`PrepareFetch::fetch_only()`]. #[derive(Debug, thiserror::Error)] #[allow(missing_docs)] -#[cfg(feature = "blocking-network-client")] pub enum Error { #[error(transparent)] Connect(#[from] crate::remote::connect::Error), @@ -15,6 +14,8 @@ pub enum Error { RemoteInit(#[from] crate::remote::init::Error), #[error("Custom configuration of remote to clone from failed")] RemoteConfiguration(#[source] Box<dyn std::error::Error + Send + Sync>), + #[error("Custom configuration of connection to use when cloning failed")] + RemoteConnection(#[source] Box<dyn std::error::Error + Send + Sync>), #[error(transparent)] RemoteName(#[from] crate::config::remote::symbolic_name::Error), #[error("Failed to load repo-local git configuration before writing")] @@ -26,7 +27,7 @@ pub enum Error { #[error("The remote HEAD points to a reference named {head_ref_name:?} which is invalid.")] InvalidHeadRef { source: gix_validate::refname::Error, - head_ref_name: BString, + head_ref_name: crate::bstr::BString, }, #[error("Failed to update HEAD with values from remote")] HeadUpdate(#[from] crate::reference::edit::Error), @@ -43,12 +44,11 @@ impl PrepareFetch { /// it was newly initialized. /// /// Note that all data we created will be removed once this instance drops if the operation wasn't successful. - #[cfg(feature = "blocking-network-client")] pub fn fetch_only<P>( &mut self, - progress: P, + mut progress: P, should_interrupt: &std::sync::atomic::AtomicBool, - ) -> Result<(Repository, crate::remote::fetch::Outcome), Error> + ) -> Result<(crate::Repository, crate::remote::fetch::Outcome), Error> where P: crate::Progress, P::SubProgress: 'static, @@ -100,14 +100,19 @@ impl PrepareFetch { ) .expect("valid") .to_owned(); - let pending_pack: remote::fetch::Prepare<'_, '_, _, _> = - remote.connect(remote::Direction::Fetch, progress)?.prepare_fetch({ + let pending_pack: remote::fetch::Prepare<'_, '_, _> = { + let mut connection = remote.connect(remote::Direction::Fetch)?; + if let Some(f) = self.configure_connection.as_mut() { + f(&mut connection).map_err(|err| Error::RemoteConnection(err))?; + } + connection.prepare_fetch(&mut progress, { let mut opts = self.fetch_options.clone(); if !opts.extra_refspecs.contains(&head_refspec) { opts.extra_refspecs.push(head_refspec) } opts - })?; + })? + }; if pending_pack.ref_map().object_hash != repo.object_hash() { unimplemented!("configure repository to expect a different object hash as advertised by the server") } @@ -121,7 +126,8 @@ impl PrepareFetch { .with_reflog_message(RefLogMessage::Override { message: reflog_message.clone(), }) - .receive(should_interrupt)?; + .with_shallow(self.shallow.clone()) + .receive(progress, should_interrupt)?; util::append_config_to_repo_config(repo, config); util::update_head( @@ -135,7 +141,6 @@ impl PrepareFetch { } /// Similar to [`fetch_only()`][Self::fetch_only()`], but passes ownership to a utility type to configure a checkout operation. - #[cfg(feature = "blocking-network-client")] pub fn fetch_then_checkout<P>( &mut self, progress: P, @@ -150,63 +155,5 @@ impl PrepareFetch { } } -/// Builder -impl PrepareFetch { - /// Set additional options to adjust parts of the fetch operation that are not affected by the git configuration. - #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] - pub fn with_fetch_options(mut self, opts: crate::remote::ref_map::Options) -> Self { - self.fetch_options = opts; - self - } - /// Use `f` to apply arbitrary changes to the remote that is about to be used to fetch a pack. - /// - /// The passed in `remote` will be un-named and pre-configured to be a default remote as we know it from git-clone. - /// It is not yet present in the configuration of the repository, - /// but each change it will eventually be written to the configuration prior to performing a the fetch operation, - /// _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. - /// 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, - f: impl FnMut(crate::Remote<'_>) -> Result<crate::Remote<'_>, Box<dyn std::error::Error + Send + Sync>> + 'static, - ) -> Self { - self.configure_remote = Some(Box::new(f)); - self - } - - /// Set the remote's name to the given value after it was configured using the function provided via - /// [`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> { - self.remote_name = Some(crate::remote::name::validated(name)?); - Ok(self) - } -} - -/// Consumption -impl PrepareFetch { - /// Persist the contained repository as is even if an error may have occurred when fetching from the remote. - pub fn persist(mut self) -> Repository { - self.repo.take().expect("present and consumed once") - } -} - -impl Drop for PrepareFetch { - fn drop(&mut self) { - if let Some(repo) = self.repo.take() { - std::fs::remove_dir_all(repo.work_dir().unwrap_or_else(|| repo.path())).ok(); - } - } -} - -impl From<PrepareFetch> for Repository { - fn from(prep: PrepareFetch) -> Self { - prep.persist() - } -} - #[cfg(feature = "blocking-network-client")] mod util; diff --git a/vendor/gix/src/clone/mod.rs b/vendor/gix/src/clone/mod.rs index 249a66a42..43024e0b4 100644 --- a/vendor/gix/src/clone/mod.rs +++ b/vendor/gix/src/clone/mod.rs @@ -1,10 +1,16 @@ #![allow(clippy::result_large_err)] use std::convert::TryInto; -use crate::{bstr::BString, config::tree::gitoxide}; +use crate::{bstr::BString, config::tree::gitoxide, remote}; type ConfigureRemoteFn = Box<dyn FnMut(crate::Remote<'_>) -> Result<crate::Remote<'_>, Box<dyn std::error::Error + Send + Sync>>>; +#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] +type ConfigureConnectionFn = Box< + dyn FnMut( + &mut remote::Connection<'_, '_, Box<dyn gix_protocol::transport::client::Transport + Send>>, + ) -> Result<(), Box<dyn std::error::Error + Send + Sync>>, +>; /// A utility to collect configuration on how to fetch from a remote and initiate a fetch operation. It will delete the newly /// created repository on when dropped without successfully finishing a fetch. @@ -16,12 +22,18 @@ pub struct PrepareFetch { remote_name: Option<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. + #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] + configure_connection: Option<ConfigureConnectionFn>, /// Options for preparing a fetch operation. #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] - fetch_options: crate::remote::ref_map::Options, + fetch_options: remote::ref_map::Options, /// The url to clone from #[cfg_attr(not(feature = "blocking-network-client"), allow(dead_code))] url: gix_url::Url, + /// How to handle shallow clones + #[cfg_attr(not(feature = "blocking-network-client"), allow(dead_code))] + shallow: remote::fetch::Shallow, } /// The error returned by [`PrepareFetch::new()`]. @@ -99,6 +111,9 @@ impl PrepareFetch { repo: Some(repo), remote_name: None, configure_remote: None, + #[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))] + configure_connection: None, + shallow: remote::fetch::Shallow::NoChange, }) } } @@ -111,7 +126,41 @@ 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"))] +mod access_feat { + use crate::clone::PrepareFetch; + + /// Builder + impl PrepareFetch { + /// Set a callback to use for configuring the connection to use right before connecting to the remote. + /// + /// It is most commonly used for custom configuration. + // TODO: tests + pub fn configure_connection( + mut self, + f: impl FnMut( + &mut crate::remote::Connection<'_, '_, Box<dyn gix_protocol::transport::client::Transport + Send>>, + ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> + + 'static, + ) -> Self { + self.configure_connection = Some(Box::new(f)); + self + } + + /// Set additional options to adjust parts of the fetch operation that are not affected by the git configuration. + pub fn with_fetch_options(mut self, opts: crate::remote::ref_map::Options) -> Self { + self.fetch_options = opts; + self + } + } +} + /// +#[cfg(feature = "blocking-network-client")] pub mod fetch; /// |