Merge branch 'js/mingw-perl5lib'
authorJunio C Hamano <gitster@pobox.com>
Tue, 13 Nov 2018 13:37:20 +0000 (22:37 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 13 Nov 2018 13:37:20 +0000 (22:37 +0900)
Windows fix.

* js/mingw-perl5lib:
  mingw: unset PERL5LIB by default
  config: move Windows-specific config settings into compat/mingw.c
  config: allow for platform-specific core.* config settings
  config: rename `dummy` parameter to `cb` in git_default_config()

Documentation/config/core.txt
cache.h
compat/mingw.c
compat/mingw.h
config.c
environment.c
git-compat-util.h
t/t0029-core-unsetenvvars.sh [new file with mode: 0755]

index 30adc61..d0e6635 100644 (file)
@@ -548,6 +548,12 @@ relatively high IO latencies.  When enabled, Git will do the
 index comparison to the filesystem data in parallel, allowing
 overlapping IO's.  Defaults to true.
 
+core.unsetenvvars::
+       Windows-only: comma-separated list of environment variables'
+       names that need to be unset before spawning any other process.
+       Defaults to `PERL5LIB` to account for the fact that Git for
+       Windows insists on using its own Perl interpreter.
+
 core.createObject::
        You can set this to 'link', in which case a hardlink followed by
        a delete of the source are used to make sure that object creation
diff --git a/cache.h b/cache.h
index a4a7749..a59141f 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -906,14 +906,6 @@ int use_optional_locks(void);
 extern char comment_line_char;
 extern int auto_comment_line_char;
 
-/* Windows only */
-enum hide_dotfiles_type {
-       HIDE_DOTFILES_FALSE = 0,
-       HIDE_DOTFILES_TRUE,
-       HIDE_DOTFILES_DOTGITONLY
-};
-extern enum hide_dotfiles_type hide_dotfiles;
-
 enum log_refs_config {
        LOG_REFS_UNSET = -1,
        LOG_REFS_NONE = 0,
index 3b44dd9..e8e538a 100644 (file)
@@ -6,6 +6,7 @@
 #include "../run-command.h"
 #include "../cache.h"
 #include "win32/lazyload.h"
+#include "../config.h"
 
 #define HCAST(type, handle) ((type)(intptr_t)handle)
 
@@ -203,6 +204,35 @@ static int ask_yes_no_if_possible(const char *format, ...)
        }
 }
 
+/* Windows only */
+enum hide_dotfiles_type {
+       HIDE_DOTFILES_FALSE = 0,
+       HIDE_DOTFILES_TRUE,
+       HIDE_DOTFILES_DOTGITONLY
+};
+
+static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
+static char *unset_environment_variables;
+
+int mingw_core_config(const char *var, const char *value, void *cb)
+{
+       if (!strcmp(var, "core.hidedotfiles")) {
+               if (value && !strcasecmp(value, "dotgitonly"))
+                       hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
+               else
+                       hide_dotfiles = git_config_bool(var, value);
+               return 0;
+       }
+
+       if (!strcmp(var, "core.unsetenvvars")) {
+               free(unset_environment_variables);
+               unset_environment_variables = xstrdup(value);
+               return 0;
+       }
+
+       return 0;
+}
+
 /* Normalizes NT paths as returned by some low-level APIs. */
 static wchar_t *normalize_ntpath(wchar_t *wbuf)
 {
@@ -1181,6 +1211,27 @@ static wchar_t *make_environment_block(char **deltaenv)
        return wenvblk;
 }
 
+static void do_unset_environment_variables(void)
+{
+       static int done;
+       char *p = unset_environment_variables;
+
+       if (done || !p)
+               return;
+       done = 1;
+
+       for (;;) {
+               char *comma = strchr(p, ',');
+
+               if (comma)
+                       *comma = '\0';
+               unsetenv(p);
+               if (!comma)
+                       break;
+               p = comma + 1;
+       }
+}
+
 struct pinfo_t {
        struct pinfo_t *next;
        pid_t pid;
@@ -1199,9 +1250,12 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
        wchar_t wcmd[MAX_PATH], wdir[MAX_PATH], *wargs, *wenvblk = NULL;
        unsigned flags = CREATE_UNICODE_ENVIRONMENT;
        BOOL ret;
+       HANDLE cons;
+
+       do_unset_environment_variables();
 
        /* Determine whether or not we are associated to a console */
-       HANDLE cons = CreateFile("CONOUT$", GENERIC_WRITE,
+       cons = CreateFile("CONOUT$", GENERIC_WRITE,
                        FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL, NULL);
        if (cons == INVALID_HANDLE_VALUE) {
@@ -2438,6 +2492,8 @@ void mingw_startup(void)
        /* fix Windows specific environment settings */
        setup_windows_environment();
 
+       unset_environment_variables = xstrdup("PERL5LIB");
+
        /* initialize critical section for waitpid pinfo_t list */
        InitializeCriticalSection(&pinfo_cs);
 
index a577df0..2f1f8e3 100644 (file)
@@ -11,6 +11,9 @@ typedef _sigset_t sigset_t;
 #undef _POSIX_THREAD_SAFE_FUNCTIONS
 #endif
 
+extern int mingw_core_config(const char *var, const char *value, void *cb);
+#define platform_core_config mingw_core_config
+
 /*
  * things that are not available in header files
  */
index aa0ed85..2ffd39c 100644 (file)
--- a/config.c
+++ b/config.c
@@ -1093,7 +1093,7 @@ int git_config_color(char *dest, const char *var, const char *value)
        return 0;
 }
 
-static int git_default_core_config(const char *var, const char *value)
+static int git_default_core_config(const char *var, const char *value, void *cb)
 {
        /* This needs a better name */
        if (!strcmp(var, "core.filemode")) {
@@ -1344,14 +1344,6 @@ static int git_default_core_config(const char *var, const char *value)
                return 0;
        }
 
-       if (!strcmp(var, "core.hidedotfiles")) {
-               if (value && !strcasecmp(value, "dotgitonly"))
-                       hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
-               else
-                       hide_dotfiles = git_config_bool(var, value);
-               return 0;
-       }
-
        if (!strcmp(var, "core.partialclonefilter")) {
                return git_config_string(&core_partial_clone_filter_default,
                                         var, value);
@@ -1363,7 +1355,7 @@ static int git_default_core_config(const char *var, const char *value)
        }
 
        /* Add other config variables here and to Documentation/config.txt. */
-       return 0;
+       return platform_core_config(var, value, cb);
 }
 
 static int git_default_i18n_config(const char *var, const char *value)
@@ -1448,13 +1440,13 @@ static int git_default_mailmap_config(const char *var, const char *value)
        return 0;
 }
 
-int git_default_config(const char *var, const char *value, void *dummy)
+int git_default_config(const char *var, const char *value, void *cb)
 {
        if (starts_with(var, "core."))
-               return git_default_core_config(var, value);
+               return git_default_core_config(var, value, cb);
 
        if (starts_with(var, "user."))
-               return git_ident_config(var, value, dummy);
+               return git_ident_config(var, value, cb);
 
        if (starts_with(var, "i18n."))
                return git_default_i18n_config(var, value);
index 268310b..3465597 100644 (file)
@@ -72,7 +72,6 @@ int core_apply_sparse_checkout;
 int merge_log_config = -1;
 int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
 unsigned long pack_size_limit_cfg;
-enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
 enum log_refs_config log_all_ref_updates = LOG_REFS_UNSET;
 
 #ifndef PROTECT_HFS_DEFAULT
index 96a3f86..3a08d99 100644 (file)
@@ -342,6 +342,14 @@ typedef uintmax_t timestamp_t;
 #define _PATH_DEFPATH "/usr/local/bin:/usr/bin:/bin"
 #endif
 
+#ifndef platform_core_config
+static inline int noop_core_config(const char *var, const char *value, void *cb)
+{
+       return 0;
+}
+#define platform_core_config noop_core_config
+#endif
+
 #ifndef has_dos_drive_prefix
 static inline int git_has_dos_drive_prefix(const char *path)
 {
diff --git a/t/t0029-core-unsetenvvars.sh b/t/t0029-core-unsetenvvars.sh
new file mode 100755 (executable)
index 0000000..24ce46a
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+test_description='test the Windows-only core.unsetenvvars setting'
+
+. ./test-lib.sh
+
+if ! test_have_prereq MINGW
+then
+       skip_all='skipping Windows-specific tests'
+       test_done
+fi
+
+test_expect_success 'setup' '
+       mkdir -p "$TRASH_DIRECTORY/.git/hooks" &&
+       write_script "$TRASH_DIRECTORY/.git/hooks/pre-commit" <<-\EOF
+       echo $HOBBES >&2
+       EOF
+'
+
+test_expect_success 'core.unsetenvvars works' '
+       HOBBES=Calvin &&
+       export HOBBES &&
+       git commit --allow-empty -m with 2>err &&
+       grep Calvin err &&
+       git -c core.unsetenvvars=FINDUS,HOBBES,CALVIN \
+               commit --allow-empty -m without 2>err &&
+       ! grep Calvin err
+'
+
+test_done