diff --git a/setup.c b/setup.c index e6e749ec4b..c3301f5ab8 100644 --- a/setup.c +++ b/setup.c @@ -1726,6 +1726,31 @@ int daemonize(void) #define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates" #endif +struct template_dir_cb_data { + char *path; + int initialized; +}; + +static int template_dir_cb(const char *key, const char *value, void *d) +{ + struct template_dir_cb_data *data = d; + + if (strcmp(key, "init.templatedir")) + return 0; + + if (!value) { + data->path = NULL; + } else { + char *path = NULL; + + FREE_AND_NULL(data->path); + if (!git_config_pathname((const char **)&path, key, value)) + data->path = path ? path : xstrdup(value); + } + + return 0; +} + const char *get_template_dir(const char *option_template) { const char *template_dir = option_template; @@ -1733,15 +1758,13 @@ const char *get_template_dir(const char *option_template) if (!template_dir) template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT); if (!template_dir) { - static const char *init_template_dir; - static int initialized; + static struct template_dir_cb_data data; - if (!initialized) { - git_config_get_pathname("init.templatedir", - &init_template_dir); - initialized = 1; + if (!data.initialized) { + git_protected_config(template_dir_cb, &data); + data.initialized = 1; } - template_dir = init_template_dir; + template_dir = data.path; } if (!template_dir) { static char *dir; diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index eae6a46ef3..3e8cf9b885 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1436,4 +1436,35 @@ test_expect_success 'recursive clone respects -q' ' test_must_be_empty actual ' +test_expect_success '`submodule init` and `init.templateDir`' ' + mkdir -p tmpl/hooks && + write_script tmpl/hooks/post-checkout <<-EOF && + echo HOOK-RUN >&2 + echo I was here >hook.run + exit 1 + EOF + + test_config init.templateDir "$(pwd)/tmpl" && + test_when_finished \ + "git config --global --unset init.templateDir || true" && + ( + sane_unset GIT_TEMPLATE_DIR && + NO_SET_GIT_TEMPLATE_DIR=t && + export NO_SET_GIT_TEMPLATE_DIR && + + git config --global init.templateDir "$(pwd)/tmpl" && + test_must_fail git submodule \ + add "$submodurl" sub-global 2>err && + git config --global --unset init.templateDir && + grep HOOK-RUN err && + test_path_is_file sub-global/hook.run && + + git config init.templateDir "$(pwd)/tmpl" && + git submodule add "$submodurl" sub-local 2>err && + git config --unset init.templateDir && + ! grep HOOK-RUN err && + test_path_is_missing sub-local/hook.run + ) +' + test_done