Skip to content

Commit aeee982

Browse files
committed
feat: add Handshake::ref_map() to produce a ref-map from a V1 or V2 handshake.
1 parent a61b2ab commit aeee982

File tree

5 files changed

+72
-36
lines changed

5 files changed

+72
-36
lines changed

gitoxide-core/src/pack/receive.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::{
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::{
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
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
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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ impl RefMap {
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ impl Response {
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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,52 @@ pub(crate) mod hero {
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

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -143,33 +143,28 @@ where
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,
150150
&mut progress,
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
}

0 commit comments

Comments
 (0)