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
#![allow(clippy::result_large_err)]
use std::path::Path;
pub use git_discover::*;
use crate::{bstr::BString, ThreadSafeRepository};
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error(transparent)]
Discover(#[from] upwards::Error),
#[error(transparent)]
Open(#[from] crate::open::Error),
}
impl ThreadSafeRepository {
pub fn discover(directory: impl AsRef<Path>) -> Result<Self, Error> {
Self::discover_opts(directory, Default::default(), Default::default())
}
pub fn discover_opts(
directory: impl AsRef<Path>,
options: upwards::Options<'_>,
trust_map: git_sec::trust::Mapping<crate::open::Options>,
) -> Result<Self, Error> {
let (path, trust) = upwards_opts(directory, options)?;
let (git_dir, worktree_dir) = path.into_repository_and_work_tree_directories();
let mut options = trust_map.into_value_by_level(trust);
options.git_dir_trust = trust.into();
options.current_dir = Some(std::env::current_dir().map_err(upwards::Error::CurrentDir)?);
Self::open_from_paths(git_dir, worktree_dir, options).map_err(Into::into)
}
pub fn discover_with_environment_overrides(directory: impl AsRef<Path>) -> Result<Self, Error> {
Self::discover_with_environment_overrides_opts(directory, Default::default(), Default::default())
}
pub fn discover_with_environment_overrides_opts(
directory: impl AsRef<Path>,
mut options: upwards::Options<'_>,
trust_map: git_sec::trust::Mapping<crate::open::Options>,
) -> Result<Self, Error> {
fn apply_additional_environment(mut opts: upwards::Options<'_>) -> upwards::Options<'_> {
use crate::bstr::ByteVec;
if let Some(cross_fs) = std::env::var_os("GIT_DISCOVERY_ACROSS_FILESYSTEM")
.and_then(|v| Vec::from_os_string(v).ok().map(BString::from))
{
if let Ok(b) = git_config::Boolean::try_from(cross_fs.as_ref()) {
opts.cross_fs = b.into();
}
}
opts
}
if std::env::var_os("GIT_DIR").is_some() {
return Self::open_with_environment_overrides(directory.as_ref(), trust_map).map_err(Error::Open);
}
options = apply_additional_environment(options.apply_environment());
Self::discover_opts(directory, options, trust_map)
}
}