Skip to content

Commit 9dbe264

Browse files
committed
git-wrapper: support MSys2
The original purpose of the Git wrapper is to run from inside Git for Windows' /cmd/ directory, to allow setting up some environment variables before Git is allowed to take over. Due to differences in the file system layout, MSys2 requires some changes for that to work. In addition, we must take care to set the `MSYSTEM` environment variable to `MINGW32` or `MINGW64`, respectively, to allow MSys2 to be configured correctly in case Git launches a shell or Perl script. We also need to change the `TERM` variable to `cygwin` instead of `msys`, otherwise the pager `less.exe` (spawned e.g. by `git log`) will simply crash with a message similar to this one: 1 [main] less 9832 cygwin_exception::open_stackdumpfile: Dumping stack trace to less.exe.stackdump Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 4f5f856 commit 9dbe264

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

compat/win32/git-wrapper.c

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include <shlwapi.h>
1313
#include <shellapi.h>
1414
#include <stdio.h>
15+
#include <wchar.h>
16+
17+
static WCHAR msystem_bin[64];
1518

1619
static void print_error(LPCWSTR prefix, DWORD error_number)
1720
{
@@ -36,12 +39,18 @@ static void print_error(LPCWSTR prefix, DWORD error_number)
3639

3740
static void setup_environment(LPWSTR exepath)
3841
{
39-
int len;
42+
WCHAR msystem[64];
4043
LPWSTR path2 = NULL;
44+
int len;
4145

42-
/* if not set, set TERM to msys */
46+
/* Set MSYSTEM */
47+
swprintf(msystem, sizeof(msystem),
48+
L"MINGW%d", (int) sizeof(void *) * 8);
49+
SetEnvironmentVariable(L"MSYSTEM", msystem);
50+
51+
/* if not set, set TERM to cygwin */
4352
if (!GetEnvironmentVariable(L"TERM", NULL, 0))
44-
SetEnvironmentVariable(L"TERM", L"msys");
53+
SetEnvironmentVariable(L"TERM", L"cygwin");
4554

4655
/* if not set, set PLINK_PROTOCOL to ssh */
4756
if (!GetEnvironmentVariable(L"PLINK_PROTOCOL", NULL, 0))
@@ -79,12 +88,22 @@ static void setup_environment(LPWSTR exepath)
7988
len = sizeof(WCHAR) * (len + 2 * MAX_PATH);
8089
path2 = (LPWSTR)malloc(len);
8190
wcscpy(path2, exepath);
82-
PathAppend(path2, L"bin;");
83-
/* should do this only if it exists */
84-
wcscat(path2, exepath);
85-
PathAppend(path2, L"mingw\\bin;");
86-
GetEnvironmentVariable(L"PATH", &path2[wcslen(path2)],
87-
(len/sizeof(WCHAR))-wcslen(path2));
91+
PathAppend(path2, msystem_bin);
92+
if (_waccess(path2, 0) != -1) {
93+
/* We are in an MSys2-based setup */
94+
wcscat(path2, L";");
95+
wcscat(path2, exepath);
96+
PathAppend(path2, L"usr\\bin;");
97+
}
98+
else {
99+
/* Fall back to MSys1 paths */
100+
wcscpy(path2, exepath);
101+
PathAppend(path2, L"bin;");
102+
wcscat(path2, exepath);
103+
PathAppend(path2, L"mingw\\bin;");
104+
}
105+
GetEnvironmentVariable(L"PATH", path2 + wcslen(path2),
106+
(len / sizeof(WCHAR)) - wcslen(path2));
88107
SetEnvironmentVariable(L"PATH", path2);
89108
free(path2);
90109

@@ -156,6 +175,10 @@ int main(void)
156175
LPWSTR cmd = NULL, exep = exe, prefix_args = NULL, basename;
157176
UINT codepage = 0;
158177

178+
/* Determine MSys2-based Git path. */
179+
swprintf(msystem_bin, sizeof(msystem_bin),
180+
L"mingw%d\\bin", (int) sizeof(void *) * 8);
181+
159182
/* get the installation location */
160183
GetModuleFileName(NULL, exepath, MAX_PATH);
161184
if (!PathRemoveFileSpec(exepath)) {
@@ -183,7 +206,12 @@ int main(void)
183206

184207
/* set the default exe module */
185208
wcscpy(exe, exepath);
186-
PathAppend(exe, L"bin\\git.exe");
209+
PathAppend(exe, msystem_bin);
210+
PathAppend(exe, L"git.exe");
211+
if (_waccess(exe, 0) == -1) {
212+
wcscpy(exe, exepath);
213+
PathAppend(exe, L"bin\\git.exe");
214+
}
187215
}
188216

189217
if (!prefix_args)

0 commit comments

Comments
 (0)