Skip to content

Commit a0efc0d

Browse files
committed
mingw: unset PERL5LIB by default
Git for Windows ships with its own Perl interpreter, and insists on using it, so it will most likely wreak havoc if PERL5LIB is set before launching Git. Let's just unset that environment variables when spawning processes. To make this feature extensible (and overrideable), there is a new config setting `core.unsetenvvars` that allows specifying a comma-separated list of names to unset before spawning processes. Reported by Gabriel Fuhrmann. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 4465a39 commit a0efc0d

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

Documentation/config.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,12 @@ core.longpaths::
775775
(msys, bash, tcl, perl...). Only enable this if you know what you're
776776
doing and are prepared to live with a few quirks.
777777

778+
core.unsetenvvars::
779+
EXPERIMENTAL, Windows-only: comma-separated list of environment
780+
variables' names that need to be unset before spawning any other
781+
process. Defaults to `PERL5LIB` to account for the fact that Git
782+
for Windows insists on using its own Perl interpreter.
783+
778784
core.createObject::
779785
You can set this to 'link', in which case a hardlink followed by
780786
a delete of the source are used to make sure that object creation

compat/mingw.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ enum hide_dotfiles_type {
238238
static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
239239
int core_fscache;
240240
int core_long_paths;
241+
static char *unset_environment_variables;
241242

242243
int mingw_core_config(const char *var, const char *value)
243244
{
@@ -259,6 +260,12 @@ int mingw_core_config(const char *var, const char *value)
259260
return 0;
260261
}
261262

263+
if (!strcmp(var, "core.unsetenvvars")) {
264+
free(unset_environment_variables);
265+
unset_environment_variables = xstrdup(value);
266+
return 0;
267+
}
268+
262269
return 0;
263270
}
264271

@@ -1432,6 +1439,27 @@ static wchar_t *make_environment_block(char **deltaenv)
14321439

14331440
#endif
14341441

1442+
static void do_unset_environment_variables(void)
1443+
{
1444+
static int done;
1445+
char *p = unset_environment_variables;
1446+
1447+
if (done || !p)
1448+
return;
1449+
done = 1;
1450+
1451+
for (;;) {
1452+
char *comma = strchr(p, ',');
1453+
1454+
if (comma)
1455+
*comma = '\0';
1456+
unsetenv(p);
1457+
if (!comma)
1458+
break;
1459+
p = comma + 1;
1460+
}
1461+
}
1462+
14351463
struct pinfo_t {
14361464
struct pinfo_t *next;
14371465
pid_t pid;
@@ -1450,9 +1478,12 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
14501478
wchar_t wcmd[MAX_PATH], wdir[MAX_PATH], *wargs, *wenvblk = NULL;
14511479
unsigned flags = CREATE_UNICODE_ENVIRONMENT;
14521480
BOOL ret;
1481+
HANDLE cons;
1482+
1483+
do_unset_environment_variables();
14531484

14541485
/* Determine whether or not we are associated to a console */
1455-
HANDLE cons = CreateFile("CONOUT$", GENERIC_WRITE,
1486+
cons = CreateFile("CONOUT$", GENERIC_WRITE,
14561487
FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
14571488
FILE_ATTRIBUTE_NORMAL, NULL);
14581489
if (cons == INVALID_HANDLE_VALUE) {
@@ -3035,6 +3066,8 @@ int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env)
30353066
/* fix Windows specific environment settings */
30363067
setup_windows_environment();
30373068

3069+
unset_environment_variables = xstrdup("PERL5LIB");
3070+
30383071
/* initialize critical section for waitpid pinfo_t list */
30393072
InitializeCriticalSection(&pinfo_cs);
30403073
InitializeCriticalSection(&phantom_symlinks_cs);
@@ -3111,6 +3144,8 @@ void mingw_startup(void)
31113144
/* fix Windows specific environment settings */
31123145
setup_windows_environment();
31133146

3147+
unset_environment_variables = xstrdup("PERL5LIB");
3148+
31143149
/*
31153150
* Avoid a segmentation fault when cURL tries to set the CHARSET
31163151
* variable and putenv() barfs at our nedmalloc'ed environment.

t/t0028-core-unsetenvvars.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/sh
2+
3+
test_description='test the Windows-only core.unsetenvvars setting'
4+
5+
. ./test-lib.sh
6+
7+
if ! test_have_prereq MINGW
8+
then
9+
skip_all='skipping Windows-specific tests'
10+
test_done
11+
fi
12+
13+
test_expect_success 'setup' '
14+
mkdir -p "$TRASH_DIRECTORY/.git/hooks" &&
15+
write_script "$TRASH_DIRECTORY/.git/hooks/pre-commit" <<-\EOF
16+
echo $HOBBES >&2
17+
EOF
18+
'
19+
20+
test_expect_success 'core.unsetenvvars works' '
21+
HOBBES=Calvin &&
22+
export HOBBES &&
23+
git commit --allow-empty -m with 2>err &&
24+
grep Calvin err &&
25+
git -c core.unsetenvvars=FINDUS,HOBBES,CALVIN \
26+
commit --allow-empty -m without 2>err &&
27+
! grep Calvin err
28+
'
29+
30+
test_done

0 commit comments

Comments
 (0)