Skip to content

Commit 07e633b

Browse files
committed
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 c777afe commit 07e633b

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
@@ -381,6 +381,46 @@ static int configure_via_resource(LPWSTR basename, LPWSTR exepath, LPWSTR exep,
381381
return 1;
382382
}
383383

384+
static void initialize_top_level_path(LPWSTR top_level_path, LPWSTR exepath,
385+
LPWSTR msystem_bin, int strip_count)
386+
{
387+
wcscpy(top_level_path, exepath);
388+
389+
while (strip_count) {
390+
if (strip_count < 0) {
391+
int len = wcslen(top_level_path);
392+
PathAppend(top_level_path, msystem_bin);
393+
if (_waccess(top_level_path, 0) != -1) {
394+
/* We are in an MSys2-based setup */
395+
top_level_path[len] = L'\0';
396+
return;
397+
}
398+
top_level_path[len] = L'\0';
399+
PathAppend(top_level_path, L"mingw\\bin");
400+
if (_waccess(top_level_path, 0) != -1) {
401+
/* We are in an MSys-based setup */
402+
top_level_path[len] = L'\0';
403+
return;
404+
}
405+
top_level_path[len] = L'\0';
406+
if (!(++strip_count)) {
407+
fwprintf(stderr, L"Top-level not found: %s\n",
408+
exepath);
409+
exit(1);
410+
}
411+
}
412+
413+
if (!PathRemoveFileSpec(top_level_path)) {
414+
fwprintf(stderr, L"Invalid executable path: %s\n",
415+
exepath);
416+
ExitProcess(1);
417+
}
418+
419+
if (strip_count > 0)
420+
--strip_count;
421+
}
422+
}
423+
384424
int main(void)
385425
{
386426
int r = 1, wait = 1, prefix_args_len = -1, needs_env_setup = 1,
@@ -393,14 +433,14 @@ int main(void)
393433
/* Determine MSys2-based Git path. */
394434
swprintf(msystem_bin, sizeof(msystem_bin),
395435
L"mingw%d\\bin", (int) sizeof(void *) * 8);
436+
*top_level_path = L'\0';
396437

397438
/* get the installation location */
398439
GetModuleFileName(NULL, exepath, MAX_PATH);
399440
if (!PathRemoveFileSpec(exepath)) {
400441
fwprintf(stderr, L"Invalid executable path: %s\n", exepath);
401442
ExitProcess(1);
402443
}
403-
wcscpy(top_level_path, exepath);
404444
basename = exepath + wcslen(exepath) + 1;
405445
if (configure_via_resource(basename, exepath, exep,
406446
&prefix_args, &prefix_args_len,
@@ -413,12 +453,7 @@ int main(void)
413453
static WCHAR buffer[BUFSIZE];
414454
wait = 0;
415455
allocate_console = 1;
416-
if (!PathRemoveFileSpec(top_level_path)) {
417-
fwprintf(stderr,
418-
L"Invalid executable path: %s\n",
419-
top_level_path);
420-
ExitProcess(1);
421-
}
456+
initialize_top_level_path(top_level_path, exepath, NULL, 1);
422457

423458
/* set the default exe module */
424459
wcscpy(exe, top_level_path);
@@ -454,12 +489,7 @@ int main(void)
454489
PathAppend(exe, L"git.exe");
455490
}
456491
else if (!wcsicmp(basename, L"git.exe")) {
457-
if (!PathRemoveFileSpec(top_level_path)) {
458-
fwprintf(stderr,
459-
L"Invalid executable path: %s\n",
460-
top_level_path);
461-
ExitProcess(1);
462-
}
492+
initialize_top_level_path(top_level_path, exepath, NULL, 1);
463493

464494
/* set the default exe module */
465495
wcscpy(exe, top_level_path);
@@ -473,12 +503,7 @@ int main(void)
473503
else if (!wcsicmp(basename, L"gitk.exe")) {
474504
static WCHAR buffer[BUFSIZE];
475505
allocate_console = 1;
476-
if (!PathRemoveFileSpec(top_level_path)) {
477-
fwprintf(stderr,
478-
L"Invalid executable path: %s\n",
479-
top_level_path);
480-
ExitProcess(1);
481-
}
506+
initialize_top_level_path(top_level_path, exepath, NULL, 1);
482507

483508
/* set the default exe module */
484509
wcscpy(exe, top_level_path);
@@ -497,8 +522,13 @@ int main(void)
497522
prefix_args_len = wcslen(buffer);
498523
}
499524

500-
if (needs_env_setup)
525+
if (needs_env_setup) {
526+
if (!top_level_path[0])
527+
initialize_top_level_path(top_level_path, exepath,
528+
msystem_bin, -4);
529+
501530
setup_environment(top_level_path, full_path);
531+
}
502532
cmd = fixup_commandline(exepath, &exep, &wait,
503533
prefix_args, prefix_args_len, is_git_command, skip_arguments);
504534

0 commit comments

Comments
 (0)