Skip to content

Commit c2c9fdd

Browse files
committed
Add GitConfig::from_env_paths with git-like sequence resolution
1 parent 75879b0 commit c2c9fdd

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

git-config/src/file/git_config.rs

+47-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{
33
collections::{HashMap, VecDeque},
44
convert::TryFrom,
55
fmt::Display,
6-
path::Path,
6+
path::{Path, PathBuf},
77
};
88

99
use crate::{
@@ -162,6 +162,49 @@ impl<'event> GitConfig<'event> {
162162
Ok(config)
163163
}
164164

165+
/// Constructs a `git-config` from the default cascading sequence.
166+
/// This is neither zero-alloc nor zero-copy.
167+
///
168+
/// See https://git-scm.com/docs/git-config#FILES for details.
169+
pub fn from_env_paths() -> Result<Self, ParserOrIoError<'static>> {
170+
use std::env;
171+
172+
let mut paths = vec![];
173+
174+
if let Err(_) = env::var("GIT_CONFIG_NO_SYSTEM") {
175+
if let Ok(git_config_system) = env::var("GIT_CONFIG_SYSTEM") {
176+
paths.push(PathBuf::from(git_config_system))
177+
} else {
178+
// In git the fallback is set to a build time macro which defaults to /etc/gitconfig
179+
paths.push(PathBuf::from("/etc/gitconfig"));
180+
}
181+
}
182+
183+
if let Ok(git_config_global) = env::var("GIT_CONFIG_GLOBAL") {
184+
paths.push(PathBuf::from(git_config_global));
185+
} else {
186+
// Divergence from git-config(1)
187+
// These two are supposed to share the same scope and override
188+
// rather than append according to git-config(1) documentation.
189+
if let Ok(xdg_config_home) = env::var("XDG_CONFIG_HOME") {
190+
paths.push(PathBuf::from(xdg_config_home).join("git/config"));
191+
} else if let Ok(home) = env::var("HOME") {
192+
paths.push(PathBuf::from(home).join(".config/git/config"));
193+
}
194+
195+
if let Ok(home) = env::var("HOME") {
196+
paths.push(PathBuf::from(home).join(".gitconfig"));
197+
}
198+
}
199+
200+
if let Ok(git_dir) = env::var("GIT_DIR") {
201+
paths.push(PathBuf::from(git_dir).join("config"));
202+
}
203+
204+
let paths = paths.iter().map(PathBuf::as_path).collect::<Vec<&Path>>();
205+
Self::from_paths(&paths)
206+
}
207+
165208
/// Generates a config from the environment variables. This is neither
166209
/// zero-copy nor zero-alloc. See [`git-config`'s documentation] on
167210
/// environment variable for more information.
@@ -1622,6 +1665,9 @@ mod from_paths {
16221665
}
16231666
}
16241667

1668+
#[cfg(test)]
1669+
pub mod from_env_paths {}
1670+
16251671
#[cfg(test)]
16261672
mod from_env {
16271673
use std::env;

0 commit comments

Comments
 (0)