Unified · Split
| @@ -4,6 +4,7 @@ use std::{ · 3 unmodified lines | ||
| 4 | 4 | sync::{atomic::AtomicBool, Arc}, |
| 5 | 5 | }; |
| 6 | 6 | |
| 7 | +use crate::{net, pack::receive::protocol::fetch::negotiate, OutputFormat}; | |
| 7 | 8 | #[cfg(feature = "async-client")] |
| 8 | 9 | use gix::protocol::transport::client::async_io::connect; |
| 9 | 10 | #[cfg(feature = "blocking-client")] |
| @@ -23,8 +24,6 @@ pub use gix::{ · 13 unmodified lines | ||
| 23 | 24 | NestedProgress, Progress, |
| 24 | 25 | }; |
| 25 | 26 | |
| 26 | −use crate::{net, pack::receive::protocol::fetch::negotiate, OutputFormat}; | |
| 27 | − | |
| 28 | 27 | pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3; |
| 29 | 28 | pub struct Context<W> { |
| 30 | 29 | pub thread_limit: Option<usize>, |
| @@ -65,7 +64,7 @@ where · 34 unmodified lines | ||
| 65 | 64 | .is_some(); |
| 66 | 65 | |
| 67 | 66 | let agent = gix::protocol::agent(gix::env::agent()); |
| 68 | − let mut handshake = gix::protocol::fetch::handshake( | |
| 67 | + let mut handshake: gix::protocol::Handshake = gix::protocol::fetch::handshake( | |
| 69 | 68 | &mut transport.inner, |
| 70 | 69 | gix::protocol::credentials::builtin, |
| 71 | 70 | vec![("agent".into(), Some(agent.clone()))], |
| @@ -87,21 +86,16 @@ where · 15 unmodified lines | ||
| 87 | 86 | fetch_refspecs: fetch_refspecs.clone(), |
| 88 | 87 | extra_refspecs: vec![], |
| 89 | 88 | }; |
| 90 | − let refmap = match handshake.refs.take() { | |
| 91 | − Some(refs) => gix::protocol::fetch::RefMap::from_refs(refs, &handshake.capabilities, context)?, | |
| 92 | − None => { | |
| 93 | − gix::protocol::fetch::RefMap::fetch( | |
| 94 | − &mut progress, | |
| 95 | − &handshake.capabilities, | |
| 96 | − &mut transport.inner, | |
| 97 | − user_agent.clone(), | |
| 98 | − trace_packetlines, | |
| 99 | − true, | |
| 100 | − context, | |
| 101 | − ) | |
| 102 | − .await? | |
| 103 | − } | |
| 104 | − }; | |
| 89 | + let refmap = handshake | |
| 90 | + .fetch_or_extract_refmap( | |
| 91 | + &mut progress, | |
| 92 | + &mut transport.inner, | |
| 93 | + user_agent.clone(), | |
| 94 | + trace_packetlines, | |
| 95 | + true, | |
| 96 | + context, | |
| 97 | + ) | |
| 98 | + .await?; | |
| 105 | 99 | |
| 106 | 100 | if refmap.mappings.is_empty() && !refmap.remote_refs.is_empty() { |
| 107 | 101 | return Err(Error::NoMapping { |
| @@ -94,6 +94,7 @@ impl RefMap { · 93 unmodified lines | ||
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | /// Create a ref-map from already obtained `remote_refs`. Use `context` to pass in refspecs. |
| 97 | + /// `capabilities` are used to determine the object format. | |
| 97 | 98 | pub fn from_refs(remote_refs: Vec<Ref>, capabilities: &Capabilities, context: Context) -> Result<RefMap, Error> { |
| 98 | 99 | let all_refspecs = context.aggregate_refspecs(); |
| 99 | 100 | let Context { |
| @@ -185,7 +185,7 @@ impl Response { · 184 unmodified lines | ||
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | /// Append the given `updates` which may have been obtained from a |
| 188 | − /// (handshake::Outcome)[crate::handshake::Handshake::v1_shallow_updates]. | |
| 188 | + /// (handshake::Outcome)[crate::Handshake::v1_shallow_updates]. | |
| 189 | 189 | /// |
| 190 | 190 | /// In V2, these are received as part of the pack, but V1 sends them early, so we |
| 191 | 191 | /// offer to re-integrate them here. |
| @@ -68,6 +68,52 @@ pub(crate) mod hero { · 67 unmodified lines | ||
| 68 | 68 | /// The server capabilities. |
| 69 | 69 | pub capabilities: gix_transport::client::Capabilities, |
| 70 | 70 | } |
| 71 | + | |
| 72 | + #[cfg(feature = "fetch")] | |
| 73 | + mod fetch { | |
| 74 | + #[cfg(feature = "async-client")] | |
| 75 | + use crate::transport::client::async_io::Transport; | |
| 76 | + #[cfg(feature = "blocking-client")] | |
| 77 | + use crate::transport::client::blocking_io::Transport; | |
| 78 | + use crate::Handshake; | |
| 79 | + use gix_features::progress::Progress; | |
| 80 | + use std::borrow::Cow; | |
| 81 | + | |
| 82 | + impl Handshake { | |
| 83 | + /// Obtain a [refmap](crate::fetch::RefMap) either from this instance, taking it out in the process, if the handshake was | |
| 84 | + /// created from a V1 connection, or use `transport` to fetch the refmap as a separate command invocation. | |
| 85 | + #[allow(clippy::result_large_err)] | |
| 86 | + #[maybe_async::maybe_async] | |
| 87 | + pub async fn fetch_or_extract_refmap<T>( | |
| 88 | + &mut self, | |
| 89 | + mut progress: impl Progress, | |
| 90 | + transport: &mut T, | |
| 91 | + user_agent: (&'static str, Option<Cow<'static, str>>), | |
| 92 | + trace_packetlines: bool, | |
| 93 | + prefix_from_spec_as_filter_on_remote: bool, | |
| 94 | + refmap_context: crate::fetch::refmap::init::Context, | |
| 95 | + ) -> Result<crate::fetch::RefMap, crate::fetch::refmap::init::Error> | |
| 96 | + where | |
| 97 | + T: Transport, | |
| 98 | + { | |
| 99 | + Ok(match self.refs.take() { | |
| 100 | + Some(refs) => crate::fetch::RefMap::from_refs(refs, &self.capabilities, refmap_context)?, | |
| 101 | + None => { | |
| 102 | + crate::fetch::RefMap::fetch( | |
| 103 | + &mut progress, | |
| 104 | + &self.capabilities, | |
| 105 | + transport, | |
| 106 | + user_agent, | |
| 107 | + trace_packetlines, | |
| 108 | + prefix_from_spec_as_filter_on_remote, | |
| 109 | + refmap_context, | |
| 110 | + ) | |
| 111 | + .await? | |
| 112 | + } | |
| 113 | + }) | |
| 114 | + } | |
| 115 | + } | |
| 116 | + } | |
| 71 | 117 | } |
| 72 | 118 | |
| 73 | 119 | #[cfg(feature = "handshake")] |
| @@ -143,7 +143,7 @@ where · 142 unmodified lines | ||
| 143 | 143 | if let Some(config) = self.transport_options.as_ref() { |
| 144 | 144 | self.transport.inner.configure(&**config)?; |
| 145 | 145 | } |
| 146 | − let mut handshake = gix_protocol::fetch::handshake( | |
| 146 | + let mut handshake: gix_protocol::Handshake = gix_protocol::fetch::handshake( | |
| 147 | 147 | &mut self.transport.inner, |
| 148 | 148 | authenticate, |
| 149 | 149 | handshake_parameters, |
| @@ -151,25 +151,20 @@ where · 1 unmodified line | ||
| 151 | 151 | ) |
| 152 | 152 | .await?; |
| 153 | 153 | |
| 154 | − let context = gix_protocol::fetch::refmap::init::Context { | |
| 154 | + let context = fetch::refmap::init::Context { | |
| 155 | 155 | fetch_refspecs: self.remote.fetch_specs.clone(), |
| 156 | 156 | extra_refspecs, |
| 157 | 157 | }; |
| 158 | − let ref_map = match handshake.refs.take() { | |
| 159 | − Some(refs) => fetch::RefMap::from_refs(refs, &handshake.capabilities, context)?, | |
| 160 | − None => { | |
| 161 | − gix_protocol::fetch::RefMap::fetch( | |
| 162 | − progress, | |
| 163 | − &handshake.capabilities, | |
| 164 | − &mut self.transport.inner, | |
| 165 | − self.remote.repo.config.user_agent_tuple(), | |
| 166 | − self.trace, | |
| 167 | − prefix_from_spec_as_filter_on_remote, | |
| 168 | − context, | |
| 169 | − ) | |
| 170 | − .await? | |
| 171 | − } | |
| 172 | − }; | |
| 158 | + let ref_map = handshake | |
| 159 | + .fetch_or_extract_refmap( | |
| 160 | + progress, | |
| 161 | + &mut self.transport.inner, | |
| 162 | + self.remote.repo.config.user_agent_tuple(), | |
| 163 | + self.trace, | |
| 164 | + prefix_from_spec_as_filter_on_remote, | |
| 165 | + context, | |
| 166 | + ) | |
| 167 | + .await?; | |
| 173 | 168 | self.handshake = Some(handshake); |
| 174 | 169 | Ok(ref_map) |
| 175 | 170 | } |