Skip to content

Commit 6d1c372

Browse files
committed
A more concrete sketch of how the API for obtaining mappings should look like (#450)
1 parent 5d5e211 commit 6d1c372

File tree

4 files changed

+66
-35
lines changed

4 files changed

+66
-35
lines changed

git-repository/src/remote/connection/list_refs.rs

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
use git_features::progress::Progress;
22
use git_protocol::transport::client::Transport;
33

4-
use crate::remote::{connection::HandshakeWithRefs, fetch, Connection, Direction};
4+
use crate::remote::{connection::HandshakeWithRefs, Connection, Direction};
55

6-
mod error {
7-
#[derive(Debug, thiserror::Error)]
8-
pub enum Error {
9-
#[error(transparent)]
10-
Handshake(#[from] git_protocol::fetch::handshake::Error),
11-
#[error(transparent)]
12-
ListRefs(#[from] git_protocol::fetch::refs::Error),
13-
#[error(transparent)]
14-
Transport(#[from] git_protocol::transport::client::Error),
15-
#[error(transparent)]
16-
ConfigureCredentials(#[from] crate::config::credential_helpers::Error),
17-
}
6+
/// The error returned by [`Connection::list_refs()`].
7+
#[derive(Debug, thiserror::Error)]
8+
#[allow(missing_docs)]
9+
pub enum Error {
10+
#[error(transparent)]
11+
Handshake(#[from] git_protocol::fetch::handshake::Error),
12+
#[error(transparent)]
13+
ListRefs(#[from] git_protocol::fetch::refs::Error),
14+
#[error(transparent)]
15+
Transport(#[from] git_protocol::transport::client::Error),
16+
#[error(transparent)]
17+
ConfigureCredentials(#[from] crate::config::credential_helpers::Error),
1818
}
19-
pub use error::Error;
2019

2120
impl<'a, 'repo, T, P> Connection<'a, 'repo, T, P>
2221
where
@@ -33,13 +32,6 @@ where
3332
Ok(res.refs)
3433
}
3534

36-
/// A mapping showing the objects available in refs matching our ref-specs on the remote side, along with their destination
37-
/// ref locally, if set and if there are no conflicts.
38-
#[git_protocol::maybe_async::maybe_async]
39-
pub async fn ref_mapping(self) -> Result<Vec<fetch::Mapping>, Error> {
40-
todo!()
41-
}
42-
4335
#[git_protocol::maybe_async::maybe_async]
4436
async fn fetch_refs(&mut self) -> Result<HandshakeWithRefs, Error> {
4537
let mut credentials_storage;
@@ -75,15 +67,49 @@ where
7567
};
7668
Ok(HandshakeWithRefs { outcome, refs })
7769
}
70+
}
7871

79-
/// List all references on the remote that have been filtered through our remote's [`refspecs`][crate::Remote::refspecs()]
80-
/// for _fetching_ or _pushing_ depending on `direction`.
81-
///
82-
/// This comes in the form of information of all matching tips on the remote and the object they point to, along with
83-
/// with the local tracking branch of these tips (if available).
84-
///
85-
/// Note that this doesn't fetch the objects mentioned in the tips nor does it make any change to underlying repository.
86-
pub fn list_refs_by_refspec(&mut self, _direction: Direction) -> ! {
87-
todo!()
72+
///
73+
pub mod to_mapping {
74+
use crate::remote::{fetch, Connection};
75+
use git_features::progress::Progress;
76+
use git_protocol::transport::client::Transport;
77+
78+
/// The error returned by [`Connection::list_refs_to_mapping()`].
79+
#[derive(Debug, thiserror::Error)]
80+
#[allow(missing_docs)]
81+
pub enum Error {
82+
#[error(transparent)]
83+
ListRefs(#[from] crate::remote::list_refs::Error),
84+
}
85+
86+
impl<'a, 'repo, T, P> Connection<'a, 'repo, T, P>
87+
where
88+
T: Transport,
89+
P: Progress,
90+
{
91+
/// List all references on the remote that have been filtered through our remote's [`refspecs`][crate::Remote::refspecs()]
92+
/// for _fetching_.
93+
///
94+
/// This comes in the form of all matching tips on the remote and the object they point to, along with
95+
/// with the local tracking branch of these tips (if available).
96+
///
97+
/// Note that this doesn't fetch the objects mentioned in the tips nor does it make any change to underlying repository.
98+
#[git_protocol::maybe_async::maybe_async]
99+
pub async fn list_refs_to_mapping(mut self) -> Result<Vec<fetch::Mapping>, Error> {
100+
let mappings = self.ref_mapping().await?;
101+
git_protocol::fetch::indicate_end_of_interaction(&mut self.transport)
102+
.await
103+
.map_err(|err| Error::ListRefs(crate::remote::list_refs::Error::Transport(err)))?;
104+
Ok(mappings)
105+
}
106+
107+
#[git_protocol::maybe_async::maybe_async]
108+
async fn ref_mapping(&mut self) -> Result<Vec<fetch::Mapping>, Error> {
109+
let _res = self.fetch_refs().await?;
110+
let _group = git_refspec::MatchGroup::from_fetch_specs(self.remote.fetch_specs.iter().map(|s| s.to_ref()));
111+
// group.match_remotes(res.refs.iter().map(|r| r.unpack()))
112+
Ok(Vec::new())
113+
}
88114
}
89115
}

git-repository/src/remote/connection/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub(crate) struct HandshakeWithRefs {
66
refs: Vec<git_protocol::fetch::Ref>,
77
}
88

9+
/// A function that performs a given credential action.
910
pub type CredentialsFn<'a> = Box<dyn FnMut(git_credentials::helper::Action) -> git_credentials::protocol::Result + 'a>;
1011

1112
/// A type to represent an ongoing connection to a remote host, typically with the connection already established.
@@ -65,4 +66,5 @@ mod access {
6566
}
6667
}
6768

68-
mod list_refs;
69+
///
70+
pub mod list_refs;

git-repository/src/remote/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub mod connect;
4646
#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))]
4747
mod connection;
4848
#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))]
49-
pub use connection::Connection;
49+
pub use connection::{list_refs, Connection};
5050

5151
mod access;
5252
pub(crate) mod url;

git-repository/tests/remote/list_refs.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ mod blocking_io {
2222
(version as u8).to_string().as_str(),
2323
)?;
2424
}
25+
2526
let remote = repo.find_remote("origin")?;
26-
let connection = remote.connect(Fetch, progress::Discard)?;
27-
let refs = connection.list_refs()?;
28-
assert_eq!(refs.len(), 14, "it gets all remote refs, independently of the refspec.");
27+
{
28+
let connection = remote.connect(Fetch, progress::Discard)?;
29+
let refs = connection.list_refs()?;
30+
assert_eq!(refs.len(), 14, "it gets all remote refs, independently of the refspec.");
31+
}
2932
}
3033
Ok(())
3134
}

0 commit comments

Comments
 (0)