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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use std::borrow::Cow;
use crate::{
bstr::BStr,
config::tree::{Remote, Section},
remote,
};
/// Query configuration related to remotes.
impl crate::Repository {
/// Returns a sorted list unique of symbolic names of remotes that
/// we deem [trustworthy][crate::open::Options::filter_config_section()].
///
/// # Examples
///
/// ```
/// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
/// # mod doctest { include!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/doctest.rs")); }
/// # let repo = doctest::open_repo(doctest::remote_repo_dir("clone")?)?;
/// let remote_names: Vec<_> = repo.remote_names().into_iter().map(|name| name.to_string()).collect();
///
/// assert_eq!(remote_names, vec!["myself".to_owned(), "origin".to_owned()]);
/// # Ok(()) }
/// ```
pub fn remote_names(&self) -> remote::Names<'_> {
self.config
.resolved
.sections_by_name(Remote.name())
.map(|it| {
let filter = self.filter_config_section();
it.filter(move |s| filter(s.meta()))
.filter_map(|section| section.header().subsection_name().map(Cow::Borrowed))
.collect()
})
.unwrap_or_default()
}
/// Obtain the branch-independent name for a remote for use in the given `direction`, or `None` if it could not be determined.
///
/// For _fetching_, use the only configured remote, or default to `origin` if it exists.
/// For _pushing_, use the `remote.pushDefault` trusted configuration key, or fall back to the rules for _fetching_.
///
/// # Notes
///
/// It's up to the caller to determine what to do if the current `head` is unborn or detached.
///
/// # Examples
///
/// ```
/// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
/// # mod doctest { include!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/doctest.rs")); }
/// # let repo = doctest::open_repo(doctest::remote_repo_dir("clone")?)?;
/// assert_eq!(
/// repo.remote_default_name(gix::remote::Direction::Fetch)
/// .expect("configured")
/// .as_ref(),
/// "origin"
/// );
/// assert_eq!(
/// repo.remote_default_name(gix::remote::Direction::Push)
/// .expect("configured")
/// .as_ref(),
/// "origin"
/// );
/// # Ok(()) }
/// ```
pub fn remote_default_name(&self, direction: remote::Direction) -> Option<Cow<'_, BStr>> {
let name = (direction == remote::Direction::Push)
.then(|| {
self.config
.resolved
.string_filter(Remote::PUSH_DEFAULT, &mut self.filter_config_section())
})
.flatten();
name.or_else(|| {
let names = self.remote_names();
match names.len() {
0 => None,
1 => names.into_iter().next(),
_more_than_one => {
let origin = Cow::Borrowed("origin".into());
names.contains(&origin).then_some(origin)
}
}
})
}
}