1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
use crate::bstr::{ByteSlice, ByteVec};
use crate::{remote, Reference};
use std::borrow::Cow;
/// Remotes
impl<'repo> Reference<'repo> {
/// Find the name of our remote for `direction` as configured in `branch.<name>.remote|pushRemote` respectively.
/// If `Some(<name>)` it can be used in [`Repository::find_remote(…)`][crate::Repository::find_remote()], or if `None` then
/// [Repository::remote_default_name()][crate::Repository::remote_default_name()] could be used in its place.
///
/// Return `None` if no remote is configured.
///
/// # Note
///
/// - it's recommended to use the [`remote(…)`][Self::remote()] method as it will configure the remote with additional
/// information.
/// - `branch.<name>.pushRemote` falls back to `branch.<name>.remote`.
pub fn remote_name(&self, direction: remote::Direction) -> Option<Cow<'repo, str>> {
let name = self.name().shorten().to_str().ok()?;
let config = &self.repo.config.resolved;
(direction == remote::Direction::Push)
.then(|| {
config
.string("branch", Some(name), "pushRemote")
.or_else(|| config.string("remote", None, "pushDefault"))
})
.flatten()
.or_else(|| config.string("branch", Some(name), "remote"))
.and_then(|name| match name {
Cow::Borrowed(n) => n.to_str().ok().map(Cow::Borrowed),
Cow::Owned(n) => Vec::from(n).into_string().ok().map(Cow::Owned),
})
}
/// Like [`remote_name(…)`][Self::remote_name()], but configures the returned `Remote` with additional information like
///
/// - `branch.<name>.merge` to know which branch on the remote side corresponds to this one for merging when pulling.
pub fn remote(
&self,
direction: remote::Direction,
) -> Option<Result<crate::Remote<'repo>, remote::find::existing::Error>> {
let name = self.remote_name(direction)?;
// TODO: use `branch.<name>.merge`
self.repo.find_remote(name.as_ref()).into()
}
}