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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::{convert::TryInto, path::PathBuf, time::Duration};
use git_lock::acquire::Fail;
use crate::{config::Cache, remote, repository::identity};
impl Cache {
pub(crate) fn personas(&self) -> &identity::Personas {
self.personas
.get_or_init(|| identity::Personas::from_config_and_env(&self.resolved, self.git_prefix))
}
pub(crate) fn url_rewrite(&self) -> &remote::url::Rewrite {
self.url_rewrite
.get_or_init(|| remote::url::Rewrite::from_config(&self.resolved, self.filter_config_section))
}
#[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
pub(crate) fn url_scheme(
&self,
) -> Result<&remote::url::SchemePermission, remote::url::scheme_permission::init::Error> {
self.url_scheme.get_or_try_init(|| {
remote::url::SchemePermission::from_config(&self.resolved, self.git_prefix, self.filter_config_section)
})
}
pub(crate) fn lock_timeout(
&self,
) -> Result<(git_lock::acquire::Fail, git_lock::acquire::Fail), git_config::value::Error> {
enum Kind {
RefFiles,
RefPackFile,
}
let mut out: [git_lock::acquire::Fail; 2] = Default::default();
for (idx, kind) in [Kind::RefFiles, Kind::RefPackFile].iter().enumerate() {
let (key, default_ms) = match kind {
Kind::RefFiles => ("filesRefLockTimeout", 100),
Kind::RefPackFile => ("packedRefsTimeout", 1000),
};
let mk_default = || Fail::AfterDurationWithBackoff(Duration::from_millis(default_ms));
let mut fnp = self.filter_config_section;
let lock_mode = match self.resolved.integer_filter("core", None, key, &mut fnp) {
Some(Ok(val)) if val < 0 => Fail::AfterDurationWithBackoff(Duration::from_secs(u64::MAX)),
Some(Ok(val)) if val == 0 => Fail::Immediately,
Some(Ok(val)) => Fail::AfterDurationWithBackoff(Duration::from_millis(
val.try_into().expect("i64 can be repsented by u64"),
)),
Some(Err(_)) if self.lenient_config => mk_default(),
Some(Err(err)) => return Err(err),
None => mk_default(),
};
out[idx] = lock_mode;
}
Ok((out[0], out[1]))
}
pub(crate) fn excludes_file(&self) -> Result<Option<PathBuf>, git_config::path::interpolate::Error> {
let home = self.home_dir();
let install_dir = crate::path::install_dir().ok();
let ctx = crate::config::cache::interpolate_context(install_dir.as_deref(), home.as_deref());
match self
.resolved
.path_filter("core", None, "excludesFile", &mut self.filter_config_section.clone())
.map(|p| p.interpolate(ctx).map(|p| p.into_owned()))
.transpose()
{
Ok(f) => Ok(f),
Err(_err) if self.lenient_config => Ok(None),
Err(err) => Err(err),
}
}
pub fn xdg_config_path(
&self,
resource_file_name: &str,
) -> Result<Option<PathBuf>, git_sec::permission::Error<PathBuf>> {
std::env::var_os("XDG_CONFIG_HOME")
.map(|path| (path, &self.xdg_config_home_env))
.or_else(|| std::env::var_os("HOME").map(|path| (path, &self.home_env)))
.and_then(|(base, permission)| {
let resource = std::path::PathBuf::from(base).join("git").join(resource_file_name);
permission.check(resource).transpose()
})
.transpose()
}
pub fn home_dir(&self) -> Option<PathBuf> {
std::env::var_os("HOME")
.map(PathBuf::from)
.and_then(|path| self.home_env.check_opt(path))
}
}