Skip to content

Commit 48fdf5d

Browse files
committed
refactor
1 parent 19a0051 commit 48fdf5d

File tree

8 files changed

+82
-92
lines changed

8 files changed

+82
-92
lines changed

gitoxide-core/src/pack/receive.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,21 @@ where
8383
.collect::<Result<_, _>>()?;
8484
let user_agent = ("agent", Some(agent.clone().into()));
8585

86-
let fetch_opts = gix::protocol::fetch::refmap::init::Options::fetch(fetch_refspecs.clone());
86+
let context = gix::protocol::fetch::refmap::init::Context {
87+
fetch_refspecs: fetch_refspecs.clone(),
88+
extra_refspecs: vec![],
89+
};
8790
let refmap = match handshake.refs.take() {
88-
Some(refs) => gix::protocol::fetch::RefMap::from_refs(refs, &handshake.capabilities, fetch_opts)?,
91+
Some(refs) => gix::protocol::fetch::RefMap::from_refs(refs, &handshake.capabilities, context)?,
8992
None => {
90-
gix::protocol::fetch::RefMap::new(
93+
gix::protocol::fetch::RefMap::fetch(
9194
&mut progress,
9295
&handshake.capabilities,
9396
&mut transport.inner,
9497
user_agent.clone(),
9598
trace_packetlines,
96-
fetch_opts,
99+
true,
100+
context,
97101
)
98102
.await?
99103
}

gix-protocol/src/fetch/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
///
66
/// * [handshake](handshake())
77
/// * **ls-refs**
8-
/// * [get available refs by refspecs](RefMap::new())
8+
/// * [get available refs by refspecs](RefMap::fetch())
99
/// * **fetch pack**
1010
/// * `negotiate` until a pack can be received (TBD)
1111
/// * [officially terminate the connection](crate::indicate_end_of_interaction())

gix-protocol/src/fetch/negotiate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub struct Round {
111111
/// * `graph`
112112
/// - The commit-graph for use by the `negotiator` - we populate it with tips to initialize the graph traversal.
113113
/// * `ref_map`
114-
/// - The references known on the remote, as previously obtained with [`RefMap::new()`].
114+
/// - The references known on the remote, as previously obtained with [`RefMap::fetch()`].
115115
/// * `shallow`
116116
/// - How to deal with shallow repositories. It does affect how negotiations are performed.
117117
/// * `mapping_is_ignored`

gix-protocol/src/fetch/refmap/init.rs

Lines changed: 53 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
handshake::Ref,
1717
};
1818

19-
/// The error returned by [`RefMap::new()`].
19+
/// The error returned by [`RefMap::fetch()`].
2020
#[derive(Debug, thiserror::Error)]
2121
#[allow(missing_docs)]
2222
pub enum Error {
@@ -28,89 +28,60 @@ pub enum Error {
2828
ListRefs(#[from] crate::ls_refs::Error),
2929
}
3030

31-
/// For use in [`RefMap::new()`].
31+
/// For use in [`RefMap::fetch()`].
3232
#[derive(Debug, Clone)]
33-
pub struct Options {
33+
pub struct Context {
3434
/// All explicit refspecs to identify references on the remote that you are interested in.
3535
/// Note that these are copied to [`RefMap::refspecs`] for convenience, as `RefMap::mappings` refer to them by index.
36-
fetch_refspecs: Vec<gix_refspec::RefSpec>,
37-
/// Use a two-component prefix derived from the ref-spec's source, like `refs/heads/` to let the server pre-filter refs
38-
/// with great potential for savings in traffic and local CPU time. Defaults to `true`.
39-
prefix_from_spec_as_filter_on_remote: bool,
36+
pub fetch_refspecs: Vec<gix_refspec::RefSpec>,
4037
/// A list of refspecs to use as implicit refspecs which won't be saved or otherwise be part of the remote in question.
4138
///
4239
/// This is useful for handling `remote.<name>.tagOpt` for example.
43-
extra_refspecs: Vec<gix_refspec::RefSpec>,
44-
all_refspecs: Vec<gix_refspec::RefSpec>,
40+
pub extra_refspecs: Vec<gix_refspec::RefSpec>,
4541
}
4642

47-
impl Options {
48-
/// Create options to fetch the given `fetch_refspecs`.
49-
pub fn fetch(fetch_refspecs: Vec<gix_refspec::RefSpec>) -> Self {
50-
Self::new(fetch_refspecs, true, Vec::new())
51-
}
52-
53-
/// Specify all options for fetching.
54-
pub fn new(
55-
fetch_refspecs: Vec<gix_refspec::RefSpec>,
56-
prefix_from_spec_as_filter_on_remote: bool,
57-
extra_refspecs: Vec<gix_refspec::RefSpec>,
58-
) -> Self {
59-
let mut all_refspecs = fetch_refspecs.clone();
60-
all_refspecs.extend(extra_refspecs.iter().cloned());
61-
62-
Self {
63-
all_refspecs,
64-
fetch_refspecs: fetch_refspecs.clone(),
65-
prefix_from_spec_as_filter_on_remote,
66-
extra_refspecs,
67-
}
68-
}
69-
70-
fn push_prefix_arguments(&self, arguments: &mut Vec<BString>) {
71-
if !self.prefix_from_spec_as_filter_on_remote {
72-
return;
73-
}
74-
75-
let mut seen = HashSet::new();
76-
for spec in &self.all_refspecs {
77-
let spec = spec.to_ref();
78-
if seen.insert(spec.instruction()) {
79-
let mut prefixes = Vec::with_capacity(1);
80-
spec.expand_prefixes(&mut prefixes);
81-
for mut prefix in prefixes {
82-
prefix.insert_str(0, "ref-prefix ");
83-
arguments.push(prefix);
84-
}
85-
}
86-
}
43+
impl Context {
44+
fn aggregate_refspecs(&self) -> Vec<gix_refspec::RefSpec> {
45+
let mut all_refspecs = self.fetch_refspecs.clone();
46+
all_refspecs.extend(self.extra_refspecs.iter().cloned());
47+
all_refspecs
8748
}
8849
}
8950

9051
impl RefMap {
91-
/// Create a new instance by obtaining all references on the remote that have been filtered through our remote's
52+
/// Create a new instance by obtaining all references on the remote that have been filtered through our remote's specs
9253
/// for _fetching_.
9354
///
9455
/// * `progress` is used if `ls-refs` is invoked on the remote. Always the case when V2 is used.
56+
/// * `capabilities` are the capabilities of the server, obtained by a [handshake](crate::handshake()).
57+
/// * `transport` is a way to communicate with the server to obtain the reference listing.
58+
/// * `user_agent` is passed to the server.
59+
/// * `trace_packetlines` traces all packet lines if `true`, for debugging primarily.
60+
/// * `prefix_from_spec_as_filter_on_remote`
61+
/// - Use a two-component prefix derived from the ref-spec's source, like `refs/heads/` to let the server pre-filter refs
62+
/// with great potential for savings in traffic and local CPU time.
63+
/// * `context` to provide more [configuration](Context).
9564
#[allow(clippy::result_large_err)]
9665
#[maybe_async::maybe_async]
97-
pub async fn new<T>(
66+
pub async fn fetch<T>(
9867
mut progress: impl Progress,
9968
capabilities: &Capabilities,
10069
transport: &mut T,
10170
user_agent: (&'static str, Option<Cow<'static, str>>),
10271
trace_packetlines: bool,
103-
options: Options,
72+
prefix_from_spec_as_filter_on_remote: bool,
73+
context: Context,
10474
) -> Result<Self, Error>
10575
where
10676
T: Transport,
10777
{
10878
let _span = gix_trace::coarse!("gix_protocol::fetch::RefMap::new()");
79+
let all_refspecs = context.aggregate_refspecs();
10980
let remote_refs = crate::ls_refs(
11081
transport,
11182
capabilities,
11283
|_capabilities, arguments| {
113-
options.push_prefix_arguments(arguments);
84+
push_prefix_arguments(prefix_from_spec_as_filter_on_remote, arguments, &all_refspecs);
11485
Ok(crate::ls_refs::Action::Continue)
11586
},
11687
&mut progress,
@@ -119,18 +90,16 @@ impl RefMap {
11990
)
12091
.await?;
12192

122-
Self::from_refs(remote_refs, capabilities, options)
93+
Self::from_refs(remote_refs, capabilities, context)
12394
}
12495

125-
/// Create a ref-map from already obtained `remote_refs`.
126-
pub fn from_refs(remote_refs: Vec<Ref>, capabilities: &Capabilities, options: Options) -> Result<RefMap, Error> {
127-
let Options {
96+
/// Create a ref-map from already obtained `remote_refs`. Use `context` to pass in refspecs.
97+
pub fn from_refs(remote_refs: Vec<Ref>, capabilities: &Capabilities, context: Context) -> Result<RefMap, Error> {
98+
let all_refspecs = context.aggregate_refspecs();
99+
let Context {
128100
fetch_refspecs,
129101
extra_refspecs,
130-
all_refspecs,
131-
..
132-
} = options;
133-
102+
} = context;
134103
let num_explicit_specs = fetch_refspecs.len();
135104
let group = gix_refspec::MatchGroup::from_fetch_specs(all_refspecs.iter().map(gix_refspec::RefSpec::to_ref));
136105
let null = gix_hash::ObjectId::null(gix_hash::Kind::Sha1); // OK to hardcode Sha1, it's not supposed to match, ever.
@@ -191,3 +160,26 @@ impl RefMap {
191160
})
192161
}
193162
}
163+
164+
fn push_prefix_arguments(
165+
prefix_from_spec_as_filter_on_remote: bool,
166+
arguments: &mut Vec<BString>,
167+
all_refspecs: &[gix_refspec::RefSpec],
168+
) {
169+
if !prefix_from_spec_as_filter_on_remote {
170+
return;
171+
}
172+
173+
let mut seen = HashSet::new();
174+
for spec in all_refspecs {
175+
let spec = spec.to_ref();
176+
if seen.insert(spec.instruction()) {
177+
let mut prefixes = Vec::with_capacity(1);
178+
spec.expand_prefixes(&mut prefixes);
179+
for mut prefix in prefixes {
180+
prefix.insert_str(0, "ref-prefix ");
181+
arguments.push(prefix);
182+
}
183+
}
184+
}
185+
}

gix-protocol/src/fetch/types.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub struct Options<'a> {
1818
pub reject_shallow_remote: bool,
1919
}
2020

21-
/// For use in [`RefMap::new()`] and [`fetch`](crate::fetch()).
21+
/// For use in [`RefMap::fetch()`] and [`fetch`](crate::fetch()).
2222
#[cfg(feature = "handshake")]
2323
pub struct Context<'a, T> {
2424
/// The outcome of the handshake performed with the remote.
@@ -29,7 +29,7 @@ pub struct Context<'a, T> {
2929
///
3030
/// This is always done if the underlying protocol is V2, which is implied by the absence of refs in the `handshake` outcome.
3131
pub transport: &'a mut T,
32-
/// How to self-identify during the `ls-refs` call in [`RefMap::new()`] or the `fetch` call in [`fetch()`](crate::fetch()).
32+
/// How to self-identify during the `ls-refs` call in [`RefMap::fetch()`] or the `fetch` call in [`fetch()`](crate::fetch()).
3333
///
3434
/// This could be read from the `gitoxide.userAgent` configuration variable.
3535
pub user_agent: (&'static str, Option<std::borrow::Cow<'static, str>>),
@@ -123,7 +123,7 @@ mod with_fetch {
123123
/// [`refmap::SpecIndex::ExplicitInRemote`] in [`refmap::Mapping`].
124124
pub refspecs: Vec<gix_refspec::RefSpec>,
125125
/// Refspecs which have been added implicitly due to settings of the `remote`, usually pre-initialized from
126-
/// [`extra_refspecs` in RefMap options](refmap::init::Options).
126+
/// [`extra_refspecs` in RefMap options](refmap::init::Context).
127127
/// They are referred to by [`refmap::SpecIndex::Implicit`] in [`refmap::Mapping`].
128128
///
129129
/// They are never persisted nor are they typically presented to the user.

gix-protocol/src/ls_refs.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ pub(crate) mod function {
6060
indicate_end_of_interaction, Command,
6161
};
6262

63-
/// Invoke an ls-refs V2 command on `transport`, which requires a prior handshake that yielded
64-
/// server `capabilities`. `prepare_ls_refs(capabilities, arguments, features)` can be used to alter the _ls-refs_. `progress` is used to provide feedback.
65-
/// Note that `prepare_ls_refs()` is expected to add the `(agent, Some(name))` to the list of `features`.
63+
/// Invoke a ls-refs V2 command on `transport`, which requires a prior handshake that yielded
64+
/// server `capabilities`. `prepare_ls_refs(capabilities, arguments)` can be used to alter the _ls-refs_.
65+
/// `progress` is used to provide feedback.
66+
/// The `agent` information will be added to the features sent to the server.
6667
/// If `trace` is `true`, all packetlines received or sent will be passed to the facilities of the `gix-trace` crate.
6768
#[maybe_async]
6869
pub async fn ls_refs(

gix-transport/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ doctest = false
1818
default = []
1919

2020
## If set, blocking implementations of the typical git transports become available in `crate::client::blocking_io`
21-
##
22-
## If used in conjunction with an async implementation, this one takes precedence.
2321
blocking-client = ["gix-packetline/blocking-io"]
2422
## Implies `blocking-client`, and adds support for the http and https transports.
2523
http-client = [

gix/src/remote/connection/ref_map.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -151,31 +151,26 @@ where
151151
)
152152
.await?;
153153

154-
let fetch_opts = gix_protocol::fetch::refmap::init::Options::new(
155-
self.remote.fetch_specs.clone(),
156-
prefix_from_spec_as_filter_on_remote,
154+
let context = gix_protocol::fetch::refmap::init::Context {
155+
fetch_refspecs: self.remote.fetch_specs.clone(),
157156
extra_refspecs,
158-
);
159-
160-
Ok(match handshake.refs.take() {
161-
Some(refs) => {
162-
let refmap = fetch::RefMap::from_refs(refs, &handshake.capabilities, fetch_opts)?;
163-
self.handshake = Some(handshake);
164-
refmap
165-
}
157+
};
158+
let ref_map = match handshake.refs.take() {
159+
Some(refs) => fetch::RefMap::from_refs(refs, &handshake.capabilities, context)?,
166160
None => {
167-
let refmap = gix_protocol::fetch::RefMap::new(
161+
gix_protocol::fetch::RefMap::fetch(
168162
progress,
169163
&handshake.capabilities,
170164
&mut self.transport.inner,
171165
self.remote.repo.config.user_agent_tuple(),
172166
self.trace,
173-
fetch_opts,
167+
prefix_from_spec_as_filter_on_remote,
168+
context,
174169
)
175-
.await?;
176-
self.handshake = Some(handshake);
177-
refmap
170+
.await?
178171
}
179-
})
172+
};
173+
self.handshake = Some(handshake);
174+
Ok(ref_map)
180175
}
181176
}

0 commit comments

Comments
 (0)