int err = 0, complete_refs_before_fetch = 1;
int submodule_progress;
int filter_submodules = 0;
+ const char *template_dir;
+ char *template_dir_dup = NULL;
struct transport_ls_refs_options transport_ls_refs_options =
TRANSPORT_LS_REFS_OPTIONS_INIT;
usage_msg_opt(_("You must specify a repository to clone."),
builtin_clone_usage, builtin_clone_options);
+ xsetenv("GIT_CLONE_PROTECTION_ACTIVE", "true", 0 /* allow user override */);
+ template_dir = get_template_dir(option_template);
+ if (*template_dir && !is_absolute_path(template_dir))
+ template_dir = template_dir_dup =
+ absolute_pathdup(template_dir);
+ xsetenv("GIT_CLONE_TEMPLATE_DIR", template_dir, 1);
+
if (option_depth || option_since || option_not.nr)
deepen = 1;
if (option_single_branch == -1)
}
}
- init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
+ init_db(git_dir, real_git_dir, template_dir, GIT_HASH_UNKNOWN, NULL,
INIT_DB_QUIET);
if (real_git_dir) {
free(unborn_head);
free(dir);
free(path);
+ free(template_dir_dup);
UNLEAK(repo);
junk_mode = JUNK_LEAVE_ALL;
#include "run-command.h"
#include "config.h"
+static int identical_to_template_hook(const char *name, const char *path)
+{
+ const char *env = getenv("GIT_CLONE_TEMPLATE_DIR");
+ const char *template_dir = get_template_dir(env && *env ? env : NULL);
+ struct strbuf template_path = STRBUF_INIT;
+ int found_template_hook, ret;
+
+ strbuf_addf(&template_path, "%s/hooks/%s", template_dir, name);
+ found_template_hook = access(template_path.buf, X_OK) >= 0;
+#ifdef STRIP_EXTENSION
+ if (!found_template_hook) {
+ strbuf_addstr(&template_path, STRIP_EXTENSION);
+ found_template_hook = access(template_path.buf, X_OK) >= 0;
+ }
+#endif
+ if (!found_template_hook)
+ return 0;
+
+ ret = do_files_match(template_path.buf, path);
+
+ strbuf_release(&template_path);
+ return ret;
+}
+
const char *find_hook(const char *name)
{
static struct strbuf path = STRBUF_INIT;
}
return NULL;
}
+ if (!git_hooks_path && git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0) &&
+ !identical_to_template_hook(name, path.buf))
+ die(_("active `%s` hook found during `git clone`:\n\t%s\n"
+ "For security reasons, this is disallowed by default.\n"
+ "If this is intentional and the hook should actually "
+ "be run, please\nrun the command again with "
+ "`GIT_CLONE_PROTECTION_ACTIVE=false`"),
+ name, path.buf);
return path.buf;
}
git clone --filter=blob:limit=0 "file://$(pwd)/server" client
'
+test_expect_success 'clone with init.templatedir runs hooks' '
+ git init tmpl/hooks &&
+ write_script tmpl/hooks/post-checkout <<-EOF &&
+ echo HOOK-RUN >&2
+ echo I was here >hook.run
+ EOF
+ git -C tmpl/hooks add . &&
+ test_tick &&
+ git -C tmpl/hooks commit -m post-checkout &&
+
+ test_when_finished "git config --global --unset init.templateDir || :" &&
+ test_when_finished "git config --unset init.templateDir || :" &&
+ (
+ sane_unset GIT_TEMPLATE_DIR &&
+ NO_SET_GIT_TEMPLATE_DIR=t &&
+ export NO_SET_GIT_TEMPLATE_DIR &&
+
+ git -c core.hooksPath="$(pwd)/tmpl/hooks" \
+ clone tmpl/hooks hook-run-hookspath 2>err &&
+ ! grep "active .* hook found" err &&
+ test_path_is_file hook-run-hookspath/hook.run &&
+
+ git -c init.templateDir="$(pwd)/tmpl" \
+ clone tmpl/hooks hook-run-config 2>err &&
+ ! grep "active .* hook found" err &&
+ test_path_is_file hook-run-config/hook.run &&
+
+ git clone --template=tmpl tmpl/hooks hook-run-option 2>err &&
+ ! grep "active .* hook found" err &&
+ test_path_is_file hook-run-option/hook.run &&
+
+ git config --global init.templateDir "$(pwd)/tmpl" &&
+ git clone tmpl/hooks hook-run-global-config 2>err &&
+ git config --global --unset init.templateDir &&
+ ! grep "active .* hook found" err &&
+ test_path_is_file hook-run-global-config/hook.run &&
+
+ # clone ignores local `init.templateDir`; need to create
+ # a new repository because we deleted `.git/` in the
+ # `setup` test case above
+ git init local-clone &&
+ cd local-clone &&
+
+ git config init.templateDir "$(pwd)/../tmpl" &&
+ git clone ../tmpl/hooks hook-run-local-config 2>err &&
+ git config --unset init.templateDir &&
+ ! grep "active .* hook found" err &&
+ test_path_is_missing hook-run-local-config/hook.run
+ )
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd