gix_protocol/handshake/
mod.rs

1use bstr::BString;
2
3///
4pub mod refs;
5
6/// A git reference, commonly referred to as 'ref', as returned by a git server before sending a pack.
7#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub enum Ref {
10    /// A ref pointing to a `tag` object, which in turns points to an `object`, usually a commit
11    Peeled {
12        /// The name at which the ref is located, like `refs/tags/1.0`.
13        full_ref_name: BString,
14        /// The hash of the tag the ref points to.
15        tag: gix_hash::ObjectId,
16        /// The hash of the object the `tag` points to.
17        object: gix_hash::ObjectId,
18    },
19    /// A ref pointing to a commit object
20    Direct {
21        /// The name at which the ref is located, like `refs/heads/main` or `refs/tags/v1.0` for lightweight tags.
22        full_ref_name: BString,
23        /// The hash of the object the ref points to.
24        object: gix_hash::ObjectId,
25    },
26    /// A symbolic ref pointing to `target` ref, which in turn, ultimately after possibly following `tag`, points to an `object`
27    Symbolic {
28        /// The name at which the symbolic ref is located, like `HEAD`.
29        full_ref_name: BString,
30        /// The path of the ref the symbolic ref points to, like `refs/heads/main`.
31        ///
32        /// See issue [#205] for details
33        ///
34        /// [#205]: https://github.com/GitoxideLabs/gitoxide/issues/205
35        target: BString,
36        /// The hash of the annotated tag the ref points to, if present.
37        ///
38        /// Note that this field is also `None` if `full_ref_name` is a lightweight tag.
39        tag: Option<gix_hash::ObjectId>,
40        /// The hash of the object the `target` ref ultimately points to.
41        object: gix_hash::ObjectId,
42    },
43    /// A ref is unborn on the remote and just points to the initial, unborn branch, as is the case in a newly initialized repository
44    /// or dangling symbolic refs.
45    Unborn {
46        /// The name at which the ref is located, typically `HEAD`.
47        full_ref_name: BString,
48        /// The path of the ref the symbolic ref points to, like `refs/heads/main`, even though the `target` does not yet exist.
49        target: BString,
50    },
51}
52
53/// The result of the [`handshake()`][super::handshake()] function.
54#[derive(Default, Debug, Clone)]
55#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
56#[cfg(feature = "handshake")]
57pub struct Outcome {
58    /// The protocol version the server responded with. It might have downgraded the desired version.
59    pub server_protocol_version: gix_transport::Protocol,
60    /// The references reported as part of the `Protocol::V1` handshake, or `None` otherwise as V2 requires a separate request.
61    pub refs: Option<Vec<Ref>>,
62    /// Shallow updates as part of the `Protocol::V1`, to shallow a particular object.
63    /// Note that unshallowing isn't supported here.
64    pub v1_shallow_updates: Option<Vec<crate::fetch::response::ShallowUpdate>>,
65    /// The server capabilities.
66    pub capabilities: gix_transport::client::Capabilities,
67}
68
69#[cfg(feature = "handshake")]
70mod error {
71    use bstr::BString;
72    use gix_transport::client;
73
74    use crate::{credentials, handshake::refs};
75
76    /// The error returned by [`handshake()`][crate::fetch::handshake()].
77    #[derive(Debug, thiserror::Error)]
78    #[allow(missing_docs)]
79    pub enum Error {
80        #[error("Failed to obtain credentials")]
81        Credentials(#[from] credentials::protocol::Error),
82        #[error("No credentials were returned at all as if the credential helper isn't functioning unknowingly")]
83        EmptyCredentials,
84        #[error("Credentials provided for \"{url}\" were not accepted by the remote")]
85        InvalidCredentials { url: BString, source: std::io::Error },
86        #[error(transparent)]
87        Transport(#[from] client::Error),
88        #[error("The transport didn't accept the advertised server version {actual_version:?} and closed the connection client side")]
89        TransportProtocolPolicyViolation { actual_version: gix_transport::Protocol },
90        #[error(transparent)]
91        ParseRefs(#[from] refs::parse::Error),
92    }
93
94    impl gix_transport::IsSpuriousError for Error {
95        fn is_spurious(&self) -> bool {
96            match self {
97                Error::Transport(err) => err.is_spurious(),
98                _ => false,
99            }
100        }
101    }
102}
103#[cfg(feature = "handshake")]
104pub use error::Error;
105
106#[cfg(any(feature = "blocking-client", feature = "async-client"))]
107#[cfg(feature = "handshake")]
108pub(crate) mod function;