@@ -24,9 +24,9 @@ use once_cell::sync::Lazy;
2424/// more prefixes or matching a broad pattern of platform-like strings might be too broad. So only
2525/// prefixes that have been used in MSYS2 are considered.
2626///
27- /// Second, we don't recognize `usr` itself here, even though is a plausible prefix. In MSYS2, it
28- /// is the prefix for MSYS2 non-native programs, i.e. those that use `msys-2.0.dll`. But unlike the
29- /// `<platform>` names we recognize, `usr` also has an effectively unbounded range of plausible
27+ /// Second, we don't recognize `usr` itself here, even though it is a plausible prefix. In MSYS2,
28+ /// it is the prefix for MSYS2 non-native programs, i.e. those that use `msys-2.0.dll`. But unlike
29+ /// the `<platform>` names we recognize, `usr` also has an effectively unbounded range of plausible
3030/// meanings on non-Unix systems (for example, what should we take `Z:\usr` to mean?), which might
3131/// occasionally relate to subdirectories with contents controlled by different *user accounts*.
3232///
@@ -60,30 +60,44 @@ fn git_for_windows_root() -> Option<&'static Path> {
6060 GIT_ROOT . as_deref ( )
6161}
6262
63- /// Shell path fragments to concatenate to the root of a Git for Windows or MSYS2 installation.
64- ///
65- /// When appended to the root of a Git for Windows installation, these are locations where `sh.exe`
66- /// can usually be found. The leading `/` allow these to be used (only) with `raw_join()`.
63+ /// `bin` directory paths to try relative to the root of a Git for Windows or MSYS2 installation.
6764///
6865/// These are ordered so that a shim is preferred over a non-shim when they are tried in order.
69- const RAW_SH_EXE_PATH_SUFFIXES : & [ & str ] = & [ "/bin/sh.exe" , "/usr/bin/sh.exe" ] ;
70-
71- /// Concatenate a path by appending a raw suffix, which must contain its own leading separator.
72- fn raw_join ( path : & Path , raw_suffix : & str ) -> OsString {
73- let mut raw_path = OsString :: from ( path) ;
74- raw_path. push ( raw_suffix) ;
75- raw_path
76- }
66+ const BIN_DIR_FRAGMENTS : & [ & str ] = & [ "bin" , "usr/bin" ] ;
7767
78- /// Obtain a path to a `sh.exe` on Windows associated with Git, if one can be found.
68+ /// Obtain a path to an executable command on Windows associated with Git, if one can be found.
7969///
8070/// The resulting path uses only `/` separators so long as the path obtained from `git --exec-path`
8171/// does, which is the case unless it is overridden by setting `GIT_EXEC_PATH` to an unusual value.
82- pub ( super ) fn find_sh_on_windows ( ) -> Option < OsString > {
72+ ///
73+ /// This is currently only used (and only exercised in tests) for finding `sh.exe`. It may be used
74+ /// to find other executables in the future, but may require adjustment. (In particular, depending
75+ /// on the desired semantics, it should possibly also check inside a `cmd` directory, possibly also
76+ /// check inside `super::core_dir()` itself, and could safely check the latter location even if its
77+ /// value is not suitable to use in inferring any other paths.)
78+ fn find_git_associated_windows_executable ( stem : & str ) -> Option < OsString > {
8379 let git_root = git_for_windows_root ( ) ?;
8480
85- RAW_SH_EXE_PATH_SUFFIXES
81+ BIN_DIR_FRAGMENTS
8682 . iter ( )
87- . map ( |raw_suffix| raw_join ( git_root, raw_suffix) )
83+ . map ( |bin_dir_fragment| {
84+ // Perform explicit raw concatenation with `/` to avoid introducing any `\` separators.
85+ let mut raw_path = OsString :: from ( git_root) ;
86+ raw_path. push ( "/" ) ;
87+ raw_path. push ( bin_dir_fragment) ;
88+ raw_path. push ( "/" ) ;
89+ raw_path. push ( stem) ;
90+ raw_path. push ( ".exe" ) ;
91+ raw_path
92+ } )
8893 . find ( |raw_path| Path :: new ( raw_path) . is_file ( ) )
8994}
95+
96+ /// Like `find_associated_windows_executable`, but if not found, fall back to a simple filename.
97+ pub ( super ) fn find_git_associated_windows_executable_with_fallback ( stem : & str ) -> OsString {
98+ find_git_associated_windows_executable ( stem) . unwrap_or_else ( || {
99+ let mut raw_path = OsString :: from ( stem) ;
100+ raw_path. push ( ".exe" ) ;
101+ raw_path
102+ } )
103+ }
0 commit comments