Unified · Split
| @@ -4,6 +4,7 @@ use std::{ · 3 unmodified lines | |||
| 4 | sync::{atomic::AtomicBool, Arc}, | 4 | sync::{atomic::AtomicBool, Arc}, |
| 5 | }; | 5 | }; |
| 6 | 6 | ||
| 7 | use crate::{net, pack::receive::protocol::fetch::negotiate, OutputFormat}; | ||
| 7 | #[cfg(feature = "async-client")] | 8 | #[cfg(feature = "async-client")] |
| 8 | use gix::protocol::transport::client::async_io::connect; | 9 | use gix::protocol::transport::client::async_io::connect; |
| 9 | #[cfg(feature = "blocking-client")] | 10 | #[cfg(feature = "blocking-client")] |
| @@ -23,8 +24,6 @@ pub use gix::{ · 13 unmodified lines | |||
| 23 | NestedProgress, Progress, | 24 | NestedProgress, Progress, |
| 24 | }; | 25 | }; |
| 25 | 26 | ||
| 26 | use crate::{net, pack::receive::protocol::fetch::negotiate, OutputFormat}; | ||
| 27 | |||
| 28 | pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3; | 27 | pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3; |
| 29 | pub struct Context<W> { | 28 | pub struct Context<W> { |
| 30 | pub thread_limit: Option<usize>, | 29 | pub thread_limit: Option<usize>, |
| @@ -65,7 +64,7 @@ where · 34 unmodified lines | |||
| 65 | .is_some(); | 64 | .is_some(); |
| 66 | 65 | ||
| 67 | let agent = gix::protocol::agent(gix::env::agent()); | 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 | &mut transport.inner, | 68 | &mut transport.inner, |
| 70 | gix::protocol::credentials::builtin, | 69 | gix::protocol::credentials::builtin, |
| 71 | vec![("agent".into(), Some(agent.clone()))], | 70 | vec![("agent".into(), Some(agent.clone()))], |
| @@ -87,21 +86,16 @@ where · 15 unmodified lines | |||
| 87 | fetch_refspecs: fetch_refspecs.clone(), | 86 | fetch_refspecs: fetch_refspecs.clone(), |
| 88 | extra_refspecs: vec![], | 87 | extra_refspecs: vec![], |
| 89 | }; | 88 | }; |
| 90 | let refmap = match handshake.refs.take() { | 89 | let refmap = handshake |
| 91 | Some(refs) => gix::protocol::fetch::RefMap::from_refs(refs, &handshake.capabilities, context)?, | 90 | .fetch_or_extract_refmap( |
| 92 | None => { | 91 | &mut progress, |
| 93 | gix::protocol::fetch::RefMap::fetch( | 92 | &mut transport.inner, |
| 94 | &mut progress, | 93 | user_agent.clone(), |
| 95 | &handshake.capabilities, | 94 | trace_packetlines, |
| 96 | &mut transport.inner, | 95 | true, |
| 97 | user_agent.clone(), | 96 | context, |
| 98 | trace_packetlines, | 97 | ) |
| 99 | true, | 98 | .await?; |
| 100 | context, | ||
| 101 | ) | ||
| 102 | .await? | ||
| 103 | } | ||
| 104 | }; | ||
| 105 | 99 | ||
| 106 | if refmap.mappings.is_empty() && !refmap.remote_refs.is_empty() { | 100 | if refmap.mappings.is_empty() && !refmap.remote_refs.is_empty() { |
| 107 | return Err(Error::NoMapping { | 101 | return Err(Error::NoMapping { |
| @@ -94,6 +94,7 @@ impl RefMap { · 93 unmodified lines | |||
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | /// Create a ref-map from already obtained `remote_refs`. Use `context` to pass in refspecs. | 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 | pub fn from_refs(remote_refs: Vec<Ref>, capabilities: &Capabilities, context: Context) -> Result<RefMap, Error> { | 98 | pub fn from_refs(remote_refs: Vec<Ref>, capabilities: &Capabilities, context: Context) -> Result<RefMap, Error> { |
| 98 | let all_refspecs = context.aggregate_refspecs(); | 99 | let all_refspecs = context.aggregate_refspecs(); |
| 99 | let Context { | 100 | let Context { |
| @@ -185,7 +185,7 @@ impl Response { · 184 unmodified lines | |||
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | /// Append the given `updates` which may have been obtained from a | 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 | /// In V2, these are received as part of the pack, but V1 sends them early, so we | 190 | /// In V2, these are received as part of the pack, but V1 sends them early, so we |
| 191 | /// offer to re-integrate them here. | 191 | /// offer to re-integrate them here. |
| @@ -68,6 +68,52 @@ pub(crate) mod hero { · 67 unmodified lines | |||
| 68 | /// The server capabilities. | 68 | /// The server capabilities. |
| 69 | pub capabilities: gix_transport::client::Capabilities, | 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 | #[cfg(feature = "handshake")] | 119 | #[cfg(feature = "handshake")] |
| @@ -143,7 +143,7 @@ where · 142 unmodified lines | |||
| 143 | if let Some(config) = self.transport_options.as_ref() { | 143 | if let Some(config) = self.transport_options.as_ref() { |
| 144 | self.transport.inner.configure(&**config)?; | 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 | &mut self.transport.inner, | 147 | &mut self.transport.inner, |
| 148 | authenticate, | 148 | authenticate, |
| 149 | handshake_parameters, | 149 | handshake_parameters, |
| @@ -151,25 +151,20 @@ where · 1 unmodified line | |||
| 151 | ) | 151 | ) |
| 152 | .await?; | 152 | .await?; |
| 153 | 153 | ||
| 154 | let context = gix_protocol::fetch::refmap::init::Context { | 154 | let context = fetch::refmap::init::Context { |
| 155 | fetch_refspecs: self.remote.fetch_specs.clone(), | 155 | fetch_refspecs: self.remote.fetch_specs.clone(), |
| 156 | extra_refspecs, | 156 | extra_refspecs, |
| 157 | }; | 157 | }; |
| 158 | let ref_map = match handshake.refs.take() { | 158 | let ref_map = handshake |
| 159 | Some(refs) => fetch::RefMap::from_refs(refs, &handshake.capabilities, context)?, | 159 | .fetch_or_extract_refmap( |
| 160 | None => { | 160 | progress, |
| 161 | gix_protocol::fetch::RefMap::fetch( | 161 | &mut self.transport.inner, |
| 162 | progress, | 162 | self.remote.repo.config.user_agent_tuple(), |
| 163 | &handshake.capabilities, | 163 | self.trace, |
| 164 | &mut self.transport.inner, | 164 | prefix_from_spec_as_filter_on_remote, |
| 165 | self.remote.repo.config.user_agent_tuple(), | 165 | context, |
| 166 | self.trace, | 166 | ) |
| 167 | prefix_from_spec_as_filter_on_remote, | 167 | .await?; |
| 168 | context, | ||
| 169 | ) | ||
| 170 | .await? | ||
| 171 | } | ||
| 172 | }; | ||
| 173 | self.handshake = Some(handshake); | 168 | self.handshake = Some(handshake); |
| 174 | Ok(ref_map) | 169 | Ok(ref_map) |
| 175 | } | 170 | } |