Skip to content

Commit 650a1b5

Browse files
committed
fix: Parse installation config path more robustly
This adds the `-z`/`--null` and `--name-only` options in the `git` invocation that tries to obtain the configuration file path associated with the `git` installation itself. The benefits are: - Parsing is more reliable for paths containing unusual characters, because `-z`/`--null` causes all paths to be output literally. Previously, `"` characters were trimmed from the ends, but this would not always extract a correct path, because when a path contains characters that cause `git` to enclose it in double quotes, those characters are usually represented in a symbolic form, usually with `\` escapes. In some scenarios, such as usually on Windows when the escaped character is itself a `\` and not in the leading position, the mangled path would be usable, but more often it would not. - The volume of output is less, because `--name-only` casues values not to be included in the output. - The combination of `-z`/`--null` and `--name-only` makes the output format simpler, and the parsing logic is accordingly simpler. `git` has supported the `-z`/`--null` and `--name-only` options even before support for `--show-origin` was added in Git 2.8.0, so this change should have no effect on Git version compatibility.
1 parent 9df57aa commit 650a1b5

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

gix-path/src/env/git/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub(super) static EXE_INFO: Lazy<Option<BString>> = Lazy::new(|| {
9090
cmd.creation_flags(CREATE_NO_WINDOW);
9191
}
9292
// git 2.8.0 and higher support --show-origin.
93-
cmd.args(["config", "-l", "--show-origin"])
93+
cmd.args(["config", "-lz", "--show-origin", "--name-only"])
9494
.current_dir(env::temp_dir())
9595
.stdin(Stdio::null())
9696
.stderr(Stdio::null());
@@ -138,8 +138,8 @@ pub(super) fn install_config_path() -> Option<&'static BStr> {
138138

139139
fn first_file_from_config_with_origin(source: &BStr) -> Option<&BStr> {
140140
let file = source.strip_prefix(b"file:")?;
141-
let end_pos = file.find_byte(b'\t')?;
142-
file[..end_pos].trim_with(|c| c == '"').as_bstr().into()
141+
let end_pos = file.find_byte(b'\0')?;
142+
file[..end_pos].as_bstr().into()
143143
}
144144

145145
/// Given `config_path` as obtained from `install_config_path()`, return the path of the git installation base.

gix-path/src/env/git/tests.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ fn config_to_base_path() {
1717

1818
#[test]
1919
fn first_file_from_config_with_origin() {
20-
let macos = "file:/Applications/Xcode.app/Contents/Developer/usr/share/git-core/gitconfig credential.helper=osxkeychain\nfile:/Users/byron/.gitconfig push.default=simple\n";
20+
let macos =
21+
"file:/Applications/Xcode.app/Contents/Developer/usr/share/git-core/gitconfig\0credential.helper\0file:/Users/byron/.gitconfig\0push.default\0";
2122
let win_msys =
22-
"file:C:/git-sdk-64/etc/gitconfig core.symlinks=false\r\nfile:C:/git-sdk-64/etc/gitconfig core.autocrlf=true";
23-
let win_cmd = "file:C:/Program Files/Git/etc/gitconfig diff.astextplain.textconv=astextplain\r\nfile:C:/Program Files/Git/etc/gitconfig filter.lfs.clean=gix-lfs clean -- %f\r\n";
24-
let win_msys_old = "file:\"C:\\ProgramData/Git/config\" diff.astextplain.textconv=astextplain\r\nfile:\"C:\\ProgramData/Git/config\" filter.lfs.clean=git-lfs clean -- %f\r\n";
25-
let linux = "file:/home/parallels/.gitconfig core.excludesfile=~/.gitignore\n";
23+
"file:C:/git-sdk-64/etc/gitconfig\0core.symlinks\0file:C:/git-sdk-64/etc/gitconfig\0core.autocrlf\0";
24+
let win_cmd =
25+
"file:C:/Program Files/Git/etc/gitconfig\0diff.astextplain.textconv\0file:C:/Program Files/Git/etc/gitconfig\0filter.lfs.clean\0";
26+
let win_msys_old =
27+
"file:C:\\ProgramData/Git/config\0diff.astextplain.textconv\0file:C:\\ProgramData/Git/config\0filter.lfs.clean\0";
28+
let linux = "file:/home/parallels/.gitconfig\0core.excludesfile\0";
2629
let bogus = "something unexpected";
2730
let empty = "";
2831

0 commit comments

Comments
 (0)