Skip to content

Commit 7e77d40

Browse files
committed
feat: Extend ALTERNATIVE_LOCATIONS for per-user installations
When `git` is not found in a `PATH` search on Windows, common locations where Git for Windows is often installed are checked. But only systemwide installations had been checked before. This extends the locations examined to include the current user's own program files directory. This directory, if present, is expected to be the `Programs` subdirectory of the user's local application data directory, typically: C:\Users\<user>\AppData\Local\Programs When Git for Windows is installed for a user rather than systemwide, it is typically installed a `Git` subdirectory of that `Programs` directory (much as it is typically installed in a `Git` subdirectory of a directory such as `C:\Program Files` when installed systemwide). This looks for a suitable Git for Windows directory tree at such a location. It is possible for Git for Windows installations to be present both in the current user's own program files directory and systemwide. If that happens, such that both kinds of installations are able to be found, then we choose the per-user installation. This is based on the idea that an individual user may choose to install a newer or otherwise different version of Git for Windows, or that a developer may even test out a custom build by manually placing it in that directory. Because, in either case, the architecture of the Git for Windows executable may differ from what is currently installed systemwide or even from what is typically preferred, we will attempt to use a per-user build of any of the architectures Git for Windows has published, before then using the systemwide installations as done before. Although the user program files directory is under the local rather than roaming application data directory, and is thus not shared across machines on a domain, it is possible that some techniques of backing up and restoring data may restore a per-user installation of Git for Windows that is for a different machine architecture that cannot run, or that the user would not want to be used. In that case, this enhancement may actually break something that was working before. That seems fairly unlikely to occur, and it can be worked around by making a `git` command available in a `PATH` search. Nonetheless, if this is found to happen in practice, then further refinement of the `ALTERNATIVE_LOCATIONS` enumeration order may be warranted.
1 parent 082e22e commit 7e77d40

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,21 @@ where
3838
// known. So the situation where a process only passes down `ProgramFiles` sometimes happens.
3939
let varname_current = "ProgramFiles";
4040

41+
// Should give the user's local application data path on any system. If a user program files
42+
// directory exists for this user, then it should be the `Programs` subdirectory of this. If it
43+
// doesn't exist, or on a future or extremely strangely configured Windows setup where it is
44+
// somewhere else, it should still be safe to attempt to use it. (This differs from global
45+
// program files paths, which are usually subdirectories of the root of the system drive, which
46+
// limited user accounts can usually create their own arbitrarily named directories inside.)
47+
let varname_user_appdata_local = "LocalAppData";
48+
4149
// 64-bit relative bin dirs. So far, this is always `mingw64` or `clangarm64`, not `urct64` or
4250
// `clang64`. We check `clangarm64` before `mingw64`, because in the strange case that both are
4351
// available, we don't want to skip over a native ARM64 executable for an emulated x86_64 one.
44-
let suffixes_64 = [r"Git\clangarm64\bin", r"Git\mingw64\bin"].as_slice();
52+
let suffixes_64 = &[r"Git\clangarm64\bin", r"Git\mingw64\bin"][..];
4553

4654
// 32-bit relative bin dirs. So far, this is only ever `mingw32`, not `clang32`.
47-
let suffixes_32 = [r"Git\mingw32\bin"].as_slice();
55+
let suffixes_32 = &[r"Git\mingw32\bin"][..];
4856

4957
// Whichever of the 64-bit or 32-bit relative bin better matches this process's architecture.
5058
// Unlike the system architecture, the process architecture is always known at compile time.
@@ -53,7 +61,15 @@ where
5361
#[cfg(target_pointer_width = "32")]
5462
let suffixes_current = suffixes_32;
5563

64+
// Bin dirs relative to a user's local application data directory. We try each architecture.
65+
let suffixes_user = &[
66+
r"Programs\Git\clangarm64\bin",
67+
r"Programs\Git\mingw64\bin",
68+
r"Programs\Git\mingw32\bin",
69+
][..];
70+
5671
let rules = [
72+
(varname_user_appdata_local, suffixes_user),
5773
(varname_64bit, suffixes_64),
5874
(varname_x86, suffixes_32),
5975
(varname_current, suffixes_current),

0 commit comments

Comments
 (0)