Skip to content

Commit c26efb9

Browse files
committed
refactor!: split Handshake::fetch_or_extract_refmap()
1 parent 0021f9d commit c26efb9

File tree

4 files changed

+49
-29
lines changed

4 files changed

+49
-29
lines changed

gitoxide-core/src/pack/receive.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,8 @@ where
8888
extra_refspecs: vec![],
8989
};
9090
let refmap = handshake
91-
.fetch_or_extract_refmap(
92-
&mut progress,
93-
&mut transport.inner,
94-
user_agent.clone(),
95-
trace_packetlines,
96-
true,
97-
context,
98-
)
91+
.fetch_or_extract_refmap(user_agent.clone(), true, context)?
92+
.fetch(&mut progress, &mut transport.inner, trace_packetlines)
9993
.await?;
10094

10195
if refmap.mappings.is_empty() && !refmap.remote_refs.is_empty() {

gix-protocol/src/handshake/mod.rs

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,34 +79,59 @@ pub(crate) mod hero {
7979
use gix_features::progress::Progress;
8080
use std::borrow::Cow;
8181

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.
82+
/// Intermediate state while potentially fetching a refmap after the handshake.
83+
pub enum FetchRefMap<'a> {
84+
/// We already got a refmap to use from the handshake.
85+
Map(RefMap),
86+
/// We need to invoke another command to get the refmap.
87+
Command(crate::LsRefsCommand<'a>, crate::fetch::refmap::init::Context),
88+
}
89+
90+
impl FetchRefMap<'_> {
91+
/// Fetch the refmap, either by returning the existing one or invoking the command.
8592
#[allow(clippy::result_large_err)]
8693
#[maybe_async::maybe_async]
87-
pub async fn fetch_or_extract_refmap<T>(
88-
&mut self,
94+
pub async fn fetch(
95+
self,
8996
mut progress: impl Progress,
90-
transport: &mut T,
91-
user_agent: (&'static str, Option<Cow<'static, str>>),
97+
transport: &mut impl Transport,
9298
trace_packetlines: bool,
99+
) -> Result<crate::fetch::RefMap, crate::fetch::refmap::init::Error> {
100+
let (cmd, cx) = match self {
101+
FetchRefMap::Map(map) => return Ok(map),
102+
FetchRefMap::Command(cmd, cx) => (cmd, cx),
103+
};
104+
105+
let capabilities = cmd.capabilities;
106+
let remote_refs = cmd.invoke(transport, &mut progress, trace_packetlines).await?;
107+
RefMap::from_refs(remote_refs, capabilities, cx)
108+
}
109+
}
110+
111+
impl Handshake {
112+
/// Prepare fetching a [refmap](crate::fetch::RefMap) if not present in the handshake.
113+
#[allow(clippy::result_large_err)]
114+
pub fn fetch_or_extract_refmap(
115+
&mut self,
116+
user_agent: (&'static str, Option<Cow<'static, str>>),
93117
prefix_from_spec_as_filter_on_remote: bool,
94118
refmap_context: crate::fetch::refmap::init::Context,
95-
) -> Result<crate::fetch::RefMap, crate::fetch::refmap::init::Error>
96-
where
97-
T: Transport,
98-
{
119+
) -> Result<FetchRefMap<'_>, crate::fetch::refmap::init::Error> {
99120
if let Some(refs) = self.refs.take() {
100-
return crate::fetch::RefMap::from_refs(refs, &self.capabilities, refmap_context);
121+
return Ok(FetchRefMap::Map(crate::fetch::RefMap::from_refs(
122+
refs,
123+
&self.capabilities,
124+
refmap_context,
125+
)?));
101126
}
102127

103128
let _span = gix_trace::coarse!("gix_protocol::handshake::fetch_or_extract_refmap()");
104129
let all_refspecs = refmap_context.aggregate_refspecs();
105130
let prefix_refspecs = prefix_from_spec_as_filter_on_remote.then_some(&all_refspecs[..]);
106-
let remote_refs = crate::LsRefsCommand::new(prefix_refspecs, &self.capabilities, user_agent)
107-
.invoke(transport, &mut progress, trace_packetlines)
108-
.await?;
109-
RefMap::from_refs(remote_refs, &self.capabilities, refmap_context)
131+
Ok(FetchRefMap::Command(
132+
crate::LsRefsCommand::new(prefix_refspecs, &self.capabilities, user_agent),
133+
refmap_context,
134+
))
110135
}
111136
}
112137
}
@@ -146,6 +171,7 @@ mod error {
146171
}
147172
}
148173
}
174+
149175
#[cfg(feature = "handshake")]
150176
pub use error::Error;
151177

gix-protocol/src/ls_refs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub(crate) mod function {
5050

5151
/// A command to list references from a remote Git repository.
5252
pub struct LsRefsCommand<'a> {
53-
capabilities: &'a Capabilities,
53+
pub(crate) capabilities: &'a Capabilities,
5454
features: Vec<(&'static str, Option<Cow<'static, str>>)>,
5555
arguments: Vec<BString>,
5656
}

gix/src/remote/connection/ref_map.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,16 +156,16 @@ where
156156
fetch_refspecs: self.remote.fetch_specs.clone(),
157157
extra_refspecs,
158158
};
159+
159160
let ref_map = handshake
160161
.fetch_or_extract_refmap(
161-
progress,
162-
&mut self.transport.inner,
163162
self.remote.repo.config.user_agent_tuple(),
164-
self.trace,
165163
prefix_from_spec_as_filter_on_remote,
166164
context,
167-
)
165+
)?
166+
.fetch(progress, &mut self.transport.inner, self.trace)
168167
.await?;
168+
169169
self.handshake = Some(handshake);
170170
Ok(ref_map)
171171
}

0 commit comments

Comments
 (0)