From a9ac1c5e9e19a1e198399b92e21f26b3a8fcb5b6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 9 Jan 2025 17:14:50 +0100 Subject: [PATCH] feat: add `env::git_shell()` to obtain the shell Git would be using. This is particularly useful to execute Git hooks. --- gix-path/src/env/mod.rs | 17 +++++++++++++++++ gix-path/tests/path/env.rs | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/gix-path/src/env/mod.rs b/gix-path/src/env/mod.rs index 154a0d1ddfa..cdc092dcb25 100644 --- a/gix-path/src/env/mod.rs +++ b/gix-path/src/env/mod.rs @@ -28,6 +28,23 @@ pub fn installation_config_prefix() -> Option<&'static Path> { installation_config().map(git::config_to_base_path) } +/// Return the shell that Git would prefer as login shell, the shell to execute Git commands from. +/// +/// On Windows, this is the `bash.exe` bundled with it, and on Unix it's the shell specified by `SHELL`, +/// or `None` if it is truly unspecified. +pub fn login_shell() -> Option<&'static Path> { + static PATH: Lazy> = Lazy::new(|| { + if cfg!(windows) { + installation_config_prefix() + .and_then(|p| p.parent()) + .map(|p| p.join("usr").join("bin").join("bash.exe")) + } else { + std::env::var_os("SHELL").map(PathBuf::from) + } + }); + PATH.as_deref() +} + /// Return the name of the Git executable to invoke it. /// If it's in the `PATH`, it will always be a short name. /// diff --git a/gix-path/tests/path/env.rs b/gix-path/tests/path/env.rs index 69beb85b6e7..76a7666c59e 100644 --- a/gix-path/tests/path/env.rs +++ b/gix-path/tests/path/env.rs @@ -7,6 +7,13 @@ fn exe_invocation() { ); } +#[test] +fn git_shell() { + assert!(gix_path::env::login_shell() + .expect("There should always be the notion of a shell used by git") + .exists()); +} + #[test] fn installation_config() { assert_ne!(