Skip to content

Commit 17f29f9

Browse files
dschoGit for Windows Build Agent
authored andcommitted
mingw: let the Git wrapper determine the top-level directory
The Git wrapper is also used as a redirector for Git for Windows' bin\bash.exe dropin: for backwards-compatibility, bin\bash.exe exists and simply sets up the environment variables before executing the *real* bash. However, due to our logic to use the directory in which the `.exe` lives as top-level directory (or one directory below for certain, known basenames such as `git.exe` and `gitk.exe`), the `PATH` environment variable was prefixed with the `/bin/bin` and `/bin/mingw/bin` directories -- which makes no sense. Instead, let's just auto-detect the top-level directory in the common case. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 21ab20f commit 17f29f9

File tree

1 file changed

+50
-20
lines changed

1 file changed

+50
-20
lines changed

compat/win32/git-wrapper.c

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,46 @@ static int configure_via_resource(LPWSTR basename, LPWSTR exepath, LPWSTR exep,
422422
return 1;
423423
}
424424

425+
static void initialize_top_level_path(LPWSTR top_level_path, LPWSTR exepath,
426+
LPWSTR msystem_bin, int strip_count)
427+
{
428+
wcscpy(top_level_path, exepath);
429+
430+
while (strip_count) {
431+
if (strip_count < 0) {
432+
int len = wcslen(top_level_path);
433+
PathAppend(top_level_path, msystem_bin);
434+
if (_waccess(top_level_path, 0) != -1) {
435+
/* We are in an MSys2-based setup */
436+
top_level_path[len] = L'\0';
437+
return;
438+
}
439+
top_level_path[len] = L'\0';
440+
PathAppend(top_level_path, L"mingw\\bin");
441+
if (_waccess(top_level_path, 0) != -1) {
442+
/* We are in an MSys-based setup */
443+
top_level_path[len] = L'\0';
444+
return;
445+
}
446+
top_level_path[len] = L'\0';
447+
if (!(++strip_count)) {
448+
fwprintf(stderr, L"Top-level not found: %s\n",
449+
exepath);
450+
exit(1);
451+
}
452+
}
453+
454+
if (!PathRemoveFileSpec(top_level_path)) {
455+
fwprintf(stderr, L"Invalid executable path: %s\n",
456+
exepath);
457+
ExitProcess(1);
458+
}
459+
460+
if (strip_count > 0)
461+
--strip_count;
462+
}
463+
}
464+
425465
int main(void)
426466
{
427467
int r = 1, wait = 1, prefix_args_len = -1, needs_env_setup = 1,
@@ -434,14 +474,14 @@ int main(void)
434474
/* Determine MSys2-based Git path. */
435475
swprintf(msystem_bin, sizeof(msystem_bin),
436476
L"mingw%d\\bin", (int) sizeof(void *) * 8);
477+
*top_level_path = L'\0';
437478

438479
/* get the installation location */
439480
GetModuleFileName(NULL, exepath, MAX_PATH);
440481
if (!PathRemoveFileSpec(exepath)) {
441482
fwprintf(stderr, L"Invalid executable path: %s\n", exepath);
442483
ExitProcess(1);
443484
}
444-
wcscpy(top_level_path, exepath);
445485
basename = exepath + wcslen(exepath) + 1;
446486
if (configure_via_resource(basename, exepath, exep,
447487
&prefix_args, &prefix_args_len,
@@ -454,12 +494,7 @@ int main(void)
454494
static WCHAR buffer[BUFSIZE];
455495
wait = 0;
456496
allocate_console = 1;
457-
if (!PathRemoveFileSpec(top_level_path)) {
458-
fwprintf(stderr,
459-
L"Invalid executable path: %s\n",
460-
top_level_path);
461-
ExitProcess(1);
462-
}
497+
initialize_top_level_path(top_level_path, exepath, NULL, 1);
463498

464499
/* set the default exe module */
465500
wcscpy(exe, top_level_path);
@@ -495,12 +530,7 @@ int main(void)
495530
PathAppend(exe, L"git.exe");
496531
}
497532
else if (!wcsicmp(basename, L"git.exe")) {
498-
if (!PathRemoveFileSpec(top_level_path)) {
499-
fwprintf(stderr,
500-
L"Invalid executable path: %s\n",
501-
top_level_path);
502-
ExitProcess(1);
503-
}
533+
initialize_top_level_path(top_level_path, exepath, NULL, 1);
504534

505535
/* set the default exe module */
506536
wcscpy(exe, top_level_path);
@@ -514,12 +544,7 @@ int main(void)
514544
else if (!wcsicmp(basename, L"gitk.exe")) {
515545
static WCHAR buffer[BUFSIZE];
516546
allocate_console = 1;
517-
if (!PathRemoveFileSpec(top_level_path)) {
518-
fwprintf(stderr,
519-
L"Invalid executable path: %s\n",
520-
top_level_path);
521-
ExitProcess(1);
522-
}
547+
initialize_top_level_path(top_level_path, exepath, NULL, 1);
523548

524549
/* set the default exe module */
525550
wcscpy(exe, top_level_path);
@@ -538,8 +563,13 @@ int main(void)
538563
prefix_args_len = wcslen(buffer);
539564
}
540565

541-
if (needs_env_setup)
566+
if (needs_env_setup) {
567+
if (!top_level_path[0])
568+
initialize_top_level_path(top_level_path, exepath,
569+
msystem_bin, -4);
570+
542571
setup_environment(top_level_path, full_path);
572+
}
543573
cmd = fixup_commandline(exepath, &exep, &wait,
544574
prefix_args, prefix_args_len, is_git_command, skip_arguments);
545575

0 commit comments

Comments
 (0)