I'm using MSYS2/git with a proper installation of git for windows SDK Install git inside MSYS2 proper
The git.exe is in /mingw64/bin
directory (which is added to $PATH), but other packages that git needs (specifically like sh.exe
and less.exe
) are in /usr/bin
directory which I don't want to put in $PATH to avoid polluting my environment with other executables like mkdir
and dir
,...
Currently, some git commands need those packages like git config -l
which needs less
and any git command that'll open the EDITOR
will need sh.exe
.
What I want to achieve is adding less
and sh
to the PATH without adding the whole directory.
I tried adding them using methods HERE and HERE. Most of them allowed me to use sh
and less
directly from the terminal, but none of them made the dependent git commands work.
For example, creating a symlink of less
and sh
in the /mingw64/bin
directory will make the command prompt recognize these executables, but using git config -l
will give no output at all unless the directory of less
was added to $PATH
.
However, other methods (creating scripts and shortcuts,..) will make git complain "Unable to spawn sh/less", altgough cmd
and powershell
would recognize less
and sh
.
Why would the executable work from the terminal, but not with git? Especially the symlink case where git didn't complain about missing EXEs but still didn't function properly?
It sounds like you want to run Git for Windows outside of MSYS2 and you want to avoid putting all of the MSYS2's /usr/bin
directory on your PATH. It's also probably a good idea to avoid putting /mingw64/bin
on your PATH too.
I suggest making a wrapper program for git itself. It would know where git.exe is located, and know what directories to put on the PATH before running git.exe. It would simply modify the PATH and then pass all its arguments on to the correct git.exe. Since you're probably using a shell like the Windows Command Prompt that doesn't recognize Bash shell scripts, you'll probably just have to make a statically-linked native Windows executable that uses the Win32 API to do this. Then put that in its own directory, and add that directory to your PATH.
Here is some code that should work for you. However, you will have to edit MSYS2_DIR
to point to the directory where you installed MSYS2, and you will have to edit the target
string too. (Most MSYS2 users have git installed with pacman and it lives in /usr/bin
, so I didn't want to hardcode something different into this code.)
#include <windows.h>
#include <stdio.h>
#define MSYS2_DIR "C:/msys64"
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd)
{
const char * target = MSYS2_DIR "/usr/bin/git.exe";
BOOL success = SetEnvironmentVariable(
"PATH", MSYS2_DIR "/mingw64/bin;" MSYS2_DIR "/usr/bin/");
if (!success)
{
DWORD error = GetLastError();
fprintf(stderr, "Failed to set PATH: error %ld.\n", error);
return 1;
}
PROCESS_INFORMATION info;
STARTUPINFOA startup_info = {
sizeof(startup_info),
.hStdInput = GetStdHandle(STD_INPUT_HANDLE),
.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE),
.hStdError = GetStdHandle(STD_ERROR_HANDLE),
};
success = CreateProcessA(target, GetCommandLine(),
NULL, NULL, 1, 0, NULL, NULL, &startup_info, &info);
if (!success)
{
DWORD error = GetLastError();
fprintf(stderr, "Failed to start git: error %ld.\n", error);
return 1;
}
DWORD result = WaitForSingleObject(info.hProcess, INFINITE);
if (result)
{
fprintf(stderr, "Unexpected wait result: 0x%lx\n", result);
return 1;
}
DWORD code;
success = GetExitCodeProcess(info.hProcess, &code);
if (!success)
{
fprintf(stderr, "Failed to get child exit code.\n");
return 1;
}
return code;
}
You can compile this using either the 32-bit or 64-bit MinGW toolchains that MSYS2 provides. Just run gcc wrapper.c -o git
. This should create a native Windows executable with no dependencies on any MSYS2 DLLs.