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 <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Oct 30, 2018 at 11:40 UTC 0e218f91c299b0bffa281d3449884a824819a201
3 files changed +70 -1
Documentation/config.txt
+6
@@ -921,6 +921,12 @@ relatively high IO latencies. When enabled, Git will do the
921 index comparison to the filesystem data in parallel, allowing
922 overlapping IO's. Defaults to true.
923
924 +core.unsetenvvars::
925 + Windows-only: comma-separated list of environment variables'
926 + names that need to be unset before spawning any other process.
927 + Defaults to `PERL5LIB` to account for the fact that Git for
928 + Windows insists on using its own Perl interpreter.
929 +
930 core.createObject::
931 You can set this to 'link', in which case a hardlink followed by
932 a delete of the source are used to make sure that object creation
compat/mingw.c
+34 -1
@@ -212,6 +212,7 @@ enum hide_dotfiles_type {
212 };
213
214 static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
215 +static char *unset_environment_variables;
216
217 int mingw_core_config(const char *var, const char *value, void *cb)
218 {
@@ -223,6 +224,12 @@ int mingw_core_config(const char *var, const char *value, void *cb)
224 return 0;
225 }
226
227 + if (!strcmp(var, "core.unsetenvvars")) {
228 + free(unset_environment_variables);
229 + unset_environment_variables = xstrdup(value);
230 + return 0;
231 + }
232 +
233 return 0;
234 }
235
@@ -1180,6 +1187,27 @@ static wchar_t *make_environment_block(char **deltaenv)
1187 return wenvblk;
1188 }
1189
1190 +static void do_unset_environment_variables(void)
1191 +{
1192 + static int done;
1193 + char *p = unset_environment_variables;
1194 +
1195 + if (done || !p)
1196 + return;
1197 + done = 1;
1198 +
1199 + for (;;) {
1200 + char *comma = strchr(p, ',');
1201 +
1202 + if (comma)
1203 + *comma = '\0';
1204 + unsetenv(p);
1205 + if (!comma)
1206 + break;
1207 + p = comma + 1;
1208 + }
1209 +}
1210 +
1211 struct pinfo_t {
1212 struct pinfo_t *next;
1213 pid_t pid;
@@ -1198,9 +1226,12 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
1226 wchar_t wcmd[MAX_PATH], wdir[MAX_PATH], *wargs, *wenvblk = NULL;
1227 unsigned flags = CREATE_UNICODE_ENVIRONMENT;
1228 BOOL ret;
1229 + HANDLE cons;
1230 +
1231 + do_unset_environment_variables();
1232
1233 /* Determine whether or not we are associated to a console */
1203 - HANDLE cons = CreateFile("CONOUT$", GENERIC_WRITE,
1234 + cons = CreateFile("CONOUT$", GENERIC_WRITE,
1235 FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
1236 FILE_ATTRIBUTE_NORMAL, NULL);
1237 if (cons == INVALID_HANDLE_VALUE) {
@@ -2437,6 +2468,8 @@ void mingw_startup(void)
2468 /* fix Windows specific environment settings */
2469 setup_windows_environment();
2470
2471 + unset_environment_variables = xstrdup("PERL5LIB");
2472 +
2473 /* initialize critical section for waitpid pinfo_t list */
2474 InitializeCriticalSection(&pinfo_cs);
2475
t/t0029-core-unsetenvvars.sh new
+30
@@ -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