From 859aa5a3aa9dad51dca7ecc978a75b6be8272b6b Mon Sep 17 00:00:00 2001 From: Joshix Date: Wed, 15 Jan 2025 18:00:00 +0000 Subject: [PATCH] use /bin/sh for git-hooks --- git2-hooks/src/hookspath.rs | 40 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/git2-hooks/src/hookspath.rs b/git2-hooks/src/hookspath.rs index 3648676ee2..4cf6b235c0 100644 --- a/git2-hooks/src/hookspath.rs +++ b/git2-hooks/src/hookspath.rs @@ -3,7 +3,6 @@ use git2::Repository; use crate::{error::Result, HookResult, HooksError}; use std::{ - env, path::{Path, PathBuf}, process::Command, str::FromStr, @@ -111,16 +110,13 @@ impl HookPaths { let arg_str = format!("{:?} {}", hook, args.join(" ")); // Use -l to avoid "command not found" on Windows. - let bash_args = + let shell_args = vec!["-l".to_string(), "-c".to_string(), arg_str]; log::trace!("run hook '{:?}' in '{:?}'", hook, self.pwd); - let git_shell = find_bash_executable() - .or_else(find_default_unix_shell) - .unwrap_or_else(|| "bash".into()); - let output = Command::new(git_shell) - .args(bash_args) + let output = Command::new(shell()) + .args(shell_args) .with_no_window() .current_dir(&self.pwd) // This call forces Command to handle the Path environment correctly on windows, @@ -168,16 +164,22 @@ fn is_executable(path: &Path) -> bool { } #[cfg(windows)] -/// windows does not consider bash scripts to be executable so we consider everything +/// windows does not consider shell scripts to be executable so we consider everything /// to be executable (which is not far from the truth for windows platform.) const fn is_executable(_: &Path) -> bool { true } -// Find bash.exe, and avoid finding wsl's bash.exe on Windows. -// None for non-Windows. -fn find_bash_executable() -> Option { - if cfg!(windows) { +/// Return the shell that Git would use, the shell to execute commands from. +/// +/// On Windows, this is the full path to `sh.exe` bundled with it, and on +/// Unix it's `/bin/sh` as posix compatible shell. +/// If the bundled shell on Windows cannot be found, `sh` is returned as the name of a shell +/// as it could possibly be found in `PATH`. +/// Note that the returned path might not be a path on disk. +/// SEE: https://github.com/GitoxideLabs/gitoxide/commit/51bbb8646287f0a6dfa9ff0fd3852c25e001aaf0 +pub fn shell() -> PathBuf { + if cfg!(windows) { Command::new("where.exe") .arg("git") .output() @@ -190,16 +192,12 @@ fn find_bash_executable() -> Option { .as_deref() .and_then(Path::parent) .and_then(Path::parent) - .map(|p| p.join("usr/bin/bash.exe")) + .map(|p| p.join("usr/bin/sh.exe")) .filter(|p| p.exists()) - } else { - None - } -} - -// Find default shell on Unix-like OS. -fn find_default_unix_shell() -> Option { - env::var_os("SHELL").map(PathBuf::from) + .unwrap_or_else(|| "sh".into()) + } else { + "/bin/sh".into() + } } trait CommandExt {