From 3072133e5965e16f956509a600faaef482a10195 Mon Sep 17 00:00:00 2001 From: qystishere Date: Wed, 26 Nov 2025 09:45:50 +0300 Subject: [PATCH] Improve bash detection on Windows (#43455) I have git installed via [scoop](https://scoop.sh). The current implementation finds `git.exe` in scoop's shims folder and then tries to find `bash.exe` relative to it. For example, `git.exe` (shim) is located at: ``` C:\Users\\scoop\shims\git.exe ``` And the code tries to find `bash.exe` at: ``` C:\Users\\scoop\shims\..\bin\bash.exe ``` which doesn't exist. This PR changes the logic to first check if `bash.exe` is available in PATH (using `which::which`), and only falls back to the git-relative path if that fails. --- crates/util/src/shell.rs | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/crates/util/src/shell.rs b/crates/util/src/shell.rs index ba54f7b7784b45613b28067afe2748339e6b6c64..1f91939134b67a745c75afe264ceec0ef5d50f73 100644 --- a/crates/util/src/shell.rs +++ b/crates/util/src/shell.rs @@ -79,29 +79,42 @@ pub fn get_default_system_shell() -> String { } } -/// Get the default system shell, preferring git-bash on Windows. +/// Get the default system shell, preferring bash on Windows. pub fn get_default_system_shell_preferring_bash() -> String { if cfg!(windows) { - get_windows_git_bash().unwrap_or_else(|| get_windows_system_shell()) + get_windows_bash().unwrap_or_else(|| get_windows_system_shell()) } else { "/bin/sh".to_string() } } -pub fn get_windows_git_bash() -> Option { - static GIT_BASH: LazyLock> = LazyLock::new(|| { +pub fn get_windows_bash() -> Option { + use std::path::PathBuf; + + fn find_bash_in_scoop() -> Option { + let bash_exe = + PathBuf::from(std::env::var_os("USERPROFILE")?).join("scoop\\shims\\bash.exe"); + bash_exe.exists().then_some(bash_exe) + } + + fn find_bash_in_git() -> Option { // /path/to/git/cmd/git.exe/../../bin/bash.exe let git = which::which("git").ok()?; let git_bash = git.parent()?.parent()?.join("bin").join("bash.exe"); - if git_bash.is_file() { - log::info!("Found git-bash at {}", git_bash.display()); - Some(git_bash.to_string_lossy().to_string()) - } else { - None + git_bash.exists().then_some(git_bash) + } + + static BASH: LazyLock> = LazyLock::new(|| { + let bash = find_bash_in_scoop() + .or_else(|| find_bash_in_git()) + .map(|p| p.to_string_lossy().into_owned()); + if let Some(ref path) = bash { + log::info!("Found bash at {}", path); } + bash }); - (*GIT_BASH).clone() + (*BASH).clone() } pub fn get_windows_system_shell() -> String {