History

feat: add `Handshake::ref_map()` to produce a ref-map from a V1 or V2 handshake.

Sebastian Thiel committed 1 year ago

Commit aeee9821 parent a61b2ab5 files · +72 −36Browse files

Unified · Split

5 files
  1. gitoxide-core/src/pack/receive.rs +12 −18
  2. gix-protocol/src/fetch/refmap/init.rs +1 −0
  3. gix-protocol/src/fetch/response/mod.rs +1 −1
  4. gix-protocol/src/handshake/mod.rs +46 −0
  5. gix/src/remote/connection/ref_map.rs +12 −17
gitoxide-core/src/pack/receive.rs+12−18
@@ -4,6 +4,7 @@ use std::{ · 3 unmodified lines
44 sync::{atomic::AtomicBool, Arc},
55 };
66
7+use crate::{net, pack::receive::protocol::fetch::negotiate, OutputFormat};
78 #[cfg(feature = "async-client")]
89 use gix::protocol::transport::client::async_io::connect;
910 #[cfg(feature = "blocking-client")]
@@ -23,8 +24,6 @@ pub use gix::{ · 13 unmodified lines
2324 NestedProgress, Progress,
2425 };
2526
26−use crate::{net, pack::receive::protocol::fetch::negotiate, OutputFormat};
27−
2827 pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3;
2928 pub struct Context<W> {
3029 pub thread_limit: Option<usize>,
@@ -65,7 +64,7 @@ where · 34 unmodified lines
6564 .is_some();
6665
6766 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(
6968 &mut transport.inner,
7069 gix::protocol::credentials::builtin,
7170 vec![("agent".into(), Some(agent.clone()))],
@@ -87,21 +86,16 @@ where · 15 unmodified lines
8786 fetch_refspecs: fetch_refspecs.clone(),
8887 extra_refspecs: vec![],
8988 };
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?;
10599
106100 if refmap.mappings.is_empty() && !refmap.remote_refs.is_empty() {
107101 return Err(Error::NoMapping {
gix-protocol/src/fetch/refmap/init.rs+1−0
@@ -94,6 +94,7 @@ impl RefMap { · 93 unmodified lines
9494 }
9595
9696 /// Create a ref-map from already obtained `remote_refs`. Use `context` to pass in refspecs.
97+ /// `capabilities` are used to determine the object format.
9798 pub fn from_refs(remote_refs: Vec<Ref>, capabilities: &Capabilities, context: Context) -> Result<RefMap, Error> {
9899 let all_refspecs = context.aggregate_refspecs();
99100 let Context {
gix-protocol/src/fetch/response/mod.rs+1−1
@@ -185,7 +185,7 @@ impl Response { · 184 unmodified lines
185185 }
186186
187187 /// 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].
189189 ///
190190 /// In V2, these are received as part of the pack, but V1 sends them early, so we
191191 /// offer to re-integrate them here.
gix-protocol/src/handshake/mod.rs+46−0
@@ -68,6 +68,52 @@ pub(crate) mod hero { · 67 unmodified lines
6868 /// The server capabilities.
6969 pub capabilities: gix_transport::client::Capabilities,
7070 }
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+ }
71117 }
72118
73119 #[cfg(feature = "handshake")]
gix/src/remote/connection/ref_map.rs+12−17
@@ -143,7 +143,7 @@ where · 142 unmodified lines
143143 if let Some(config) = self.transport_options.as_ref() {
144144 self.transport.inner.configure(&**config)?;
145145 }
146− let mut handshake = gix_protocol::fetch::handshake(
146+ let mut handshake: gix_protocol::Handshake = gix_protocol::fetch::handshake(
147147 &mut self.transport.inner,
148148 authenticate,
149149 handshake_parameters,
@@ -151,25 +151,20 @@ where · 1 unmodified line
151151 )
152152 .await?;
153153
154− let context = gix_protocol::fetch::refmap::init::Context {
154+ let context = fetch::refmap::init::Context {
155155 fetch_refspecs: self.remote.fetch_specs.clone(),
156156 extra_refspecs,
157157 };
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?;
173168 self.handshake = Some(handshake);
174169 Ok(ref_map)
175170 }