Skip to content

Commit 842b0de

Browse files
committed
move all possible code from gix to gix-protocol.
For now, just move the code down and immediately re-integrate in `gix` to be able to use its tests to validate it.
1 parent 212ea9e commit 842b0de

File tree

5 files changed

+152
-0
lines changed

5 files changed

+152
-0
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gix-protocol/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ gix-hash = { version = "^0.15.1", path = "../gix-hash" }
5555
gix-date = { version = "^0.9.2", path = "../gix-date" }
5656
gix-credentials = { version = "^0.25.1", path = "../gix-credentials" }
5757
gix-utils = { version = "^0.1.13", path = "../gix-utils" }
58+
gix-refspec = { version = "^0.27.0", path = "../gix-refspec" }
5859

5960
thiserror = "2.0.0"
6061
serde = { version = "1.0.114", optional = true, default-features = false, features = [

gix-protocol/src/fetch/mod.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,42 @@ pub use response::Response;
99

1010
mod handshake;
1111
pub use handshake::upload_pack as handshake;
12+
13+
mod refmap;
14+
15+
/// A type to represent an ongoing connection to a remote host, typically with the connection already established.
16+
///
17+
/// It can be used to perform a variety of operations with the remote without worrying about protocol details,
18+
/// much like a remote procedure call.
19+
pub struct Connection<'a, T> {
20+
// TODO: figure out how to abstract `Remote`.
21+
pub(crate) authenticate: Option<crate::AuthenticateFn<'a>>,
22+
pub(crate) transport_options: Option<Box<dyn std::any::Any>>,
23+
pub(crate) transport: T,
24+
pub(crate) trace: bool,
25+
}
26+
27+
/// Information about the relationship between our refspecs, and remote references with their local counterparts.
28+
#[derive(Default, Debug, Clone)]
29+
#[cfg(any(feature = "blocking-client", feature = "async-client"))]
30+
pub struct RefMap {
31+
/// A mapping between a remote reference and a local tracking branch.
32+
pub mappings: Vec<refmap::Mapping>,
33+
/// Refspecs which have been added implicitly due to settings of the `remote`, possibly pre-initialized from
34+
/// [`extra_refspecs` in RefMap options][crate::remote::ref_map::Options::extra_refspecs].
35+
///
36+
/// They are never persisted nor are they typically presented to the user.
37+
pub extra_refspecs: Vec<gix_refspec::RefSpec>,
38+
/// Information about the fixes applied to the `mapping` due to validation and sanitization.
39+
pub fixes: Vec<gix_refspec::match_group::validate::Fix>,
40+
/// All refs advertised by the remote.
41+
pub remote_refs: Vec<crate::handshake::Ref>,
42+
/// Additional information provided by the server as part of the handshake.
43+
///
44+
/// Note that the `refs` field is always `None` as the refs are placed in `remote_refs`.
45+
pub handshake: crate::handshake::Outcome,
46+
/// The kind of hash used for all data sent by the server, if understood by this client implementation.
47+
///
48+
/// It was extracted from the `handshake` as advertised by the server.
49+
pub object_hash: gix_hash::Kind,
50+
}

gix-protocol/src/fetch/refmap.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/// Either an object id that the remote has or the matched remote ref itself.
2+
#[derive(Debug, Clone)]
3+
#[cfg(any(feature = "blocking-client", feature = "async-client"))]
4+
pub enum Source {
5+
/// An object id, as the matched ref-spec was an object id itself.
6+
ObjectId(gix_hash::ObjectId),
7+
/// The remote reference that matched the ref-specs name.
8+
Ref(crate::handshake::Ref),
9+
}
10+
11+
#[cfg(any(feature = "blocking-client", feature = "async-client"))]
12+
impl Source {
13+
/// Return either the direct object id we refer to or the direct target that a reference refers to.
14+
/// The latter may be a direct or a symbolic reference.
15+
/// If unborn, `None` is returned.
16+
pub fn as_id(&self) -> Option<&gix_hash::oid> {
17+
match self {
18+
Source::ObjectId(id) => Some(id),
19+
Source::Ref(r) => r.unpack().1,
20+
}
21+
}
22+
23+
/// Return the target that this symbolic ref is pointing to, or `None` if it is no symbolic ref.
24+
pub fn as_target(&self) -> Option<&bstr::BStr> {
25+
match self {
26+
Source::ObjectId(_) => None,
27+
Source::Ref(r) => match r {
28+
crate::handshake::Ref::Peeled { .. } | crate::handshake::Ref::Direct { .. } => None,
29+
crate::handshake::Ref::Symbolic { target, .. } | crate::handshake::Ref::Unborn { target, .. } => {
30+
Some(target.as_ref())
31+
}
32+
},
33+
}
34+
}
35+
36+
/// Returns the peeled id of this instance, that is the object that can't be de-referenced anymore.
37+
pub fn peeled_id(&self) -> Option<&gix_hash::oid> {
38+
match self {
39+
Source::ObjectId(id) => Some(id),
40+
Source::Ref(r) => {
41+
let (_name, target, peeled) = r.unpack();
42+
peeled.or(target)
43+
}
44+
}
45+
}
46+
47+
/// Return ourselves as the full name of the reference we represent, or `None` if this source isn't a reference but an object.
48+
pub fn as_name(&self) -> Option<&bstr::BStr> {
49+
match self {
50+
Source::ObjectId(_) => None,
51+
Source::Ref(r) => match r {
52+
crate::handshake::Ref::Unborn { full_ref_name, .. }
53+
| crate::handshake::Ref::Symbolic { full_ref_name, .. }
54+
| crate::handshake::Ref::Direct { full_ref_name, .. }
55+
| crate::handshake::Ref::Peeled { full_ref_name, .. } => Some(full_ref_name.as_ref()),
56+
},
57+
}
58+
}
59+
}
60+
61+
/// An index into various lists of refspecs that have been used in a [Mapping] of remote references to local ones.
62+
#[cfg(any(feature = "blocking-client", feature = "async-client"))]
63+
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
64+
pub enum SpecIndex {
65+
/// An index into the _refspecs of the remote_ that triggered a fetch operation.
66+
/// These refspecs are explicit and visible to the user.
67+
ExplicitInRemote(usize),
68+
/// An index into the list of [extra refspecs][crate::remote::fetch::RefMap::extra_refspecs] that are implicit
69+
/// to a particular fetch operation.
70+
Implicit(usize),
71+
}
72+
73+
#[cfg(any(feature = "blocking-client", feature = "async-client"))]
74+
impl SpecIndex {
75+
/// Depending on our index variant, get the index either from `refspecs` or from `extra_refspecs` for `Implicit` variants.
76+
pub fn get<'a>(
77+
self,
78+
refspecs: &'a [gix_refspec::RefSpec],
79+
extra_refspecs: &'a [gix_refspec::RefSpec],
80+
) -> Option<&'a gix_refspec::RefSpec> {
81+
match self {
82+
SpecIndex::ExplicitInRemote(idx) => refspecs.get(idx),
83+
SpecIndex::Implicit(idx) => extra_refspecs.get(idx),
84+
}
85+
}
86+
87+
/// If this is an `Implicit` variant, return its index.
88+
pub fn implicit_index(self) -> Option<usize> {
89+
match self {
90+
SpecIndex::Implicit(idx) => Some(idx),
91+
SpecIndex::ExplicitInRemote(_) => None,
92+
}
93+
}
94+
}
95+
96+
/// A mapping between a single remote reference and its advertised objects to a local destination which may or may not exist.
97+
#[derive(Debug, Clone)]
98+
#[cfg(any(feature = "blocking-client", feature = "async-client"))]
99+
pub struct Mapping {
100+
/// The reference on the remote side, along with information about the objects they point to as advertised by the server.
101+
pub remote: Source,
102+
/// The local tracking reference to update after fetching the object visible via `remote`.
103+
pub local: Option<bstr::BString>,
104+
/// The index into the fetch ref-specs used to produce the mapping, allowing it to be recovered.
105+
pub spec_index: SpecIndex,
106+
}

gix-protocol/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
#![cfg_attr(all(doc, feature = "document-features"), feature(doc_cfg, doc_auto_cfg))]
1111
#![deny(missing_docs, rust_2018_idioms, unsafe_code)]
1212

13+
/// A function that performs a given credential action, trying to obtain credentials for an operation that needs it.
14+
///
15+
/// Useful for both `fetch` and `push`.
16+
pub type AuthenticateFn<'a> = Box<dyn FnMut(gix_credentials::helper::Action) -> gix_credentials::protocol::Result + 'a>;
17+
1318
/// A selector for V2 commands to invoke on the server for purpose of pre-invocation validation.
1419
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
1520
pub enum Command {

0 commit comments

Comments
 (0)