diff options
-rw-r--r-- | Documentation/config.txt | 17 | ||||
-rw-r--r-- | Documentation/githooks.txt | 12 | ||||
-rw-r--r-- | cache.h | 1 | ||||
-rw-r--r-- | config.c | 3 | ||||
-rw-r--r-- | environment.c | 1 | ||||
-rw-r--r-- | run-command.c | 5 | ||||
-rwxr-xr-x | t/t1350-config-hooks-path.sh | 37 |
7 files changed, 71 insertions, 5 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt index 2cd6bdd7d2..7f8c119b2f 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -618,6 +618,23 @@ core.attributesFile:: $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/attributes is used instead. +core.hooksPath:: + By default Git will look for your hooks in the + '$GIT_DIR/hooks' directory. Set this to different path, + e.g. '/etc/git/hooks', and Git will try to find your hooks in + that directory, e.g. '/etc/git/hooks/pre-receive' instead of + in '$GIT_DIR/hooks/pre-receive'. ++ +The path can be either absolute or relative. A relative path is +taken as relative to the directory where the hooks are run (see +the "DESCRIPTION" section of linkgit:githooks[5]). ++ +This configuration variable is useful in cases where you'd like to +centrally configure your Git hooks instead of configuring them on a +per-repository basis, or as a more flexible and centralized +alternative to having an `init.templateDir` where you've changed +default hooks. + core.editor:: Commands such as `commit` and `tag` that lets you edit messages by launching an editor uses the value of this diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 30495745a0..d82e912e55 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -7,15 +7,19 @@ githooks - Hooks used by Git SYNOPSIS -------- -$GIT_DIR/hooks/* +$GIT_DIR/hooks/* (or \`git config core.hooksPath`/*) DESCRIPTION ----------- -Hooks are programs you can place in the `$GIT_DIR/hooks` directory to -trigger actions at certain points in git's execution. Hooks that don't -have the executable bit set are ignored. +Hooks are programs you can place in a hooks directory to trigger +actions at certain points in git's execution. Hooks that don't have +the executable bit set are ignored. + +By default the hooks directory is `$GIT_DIR/hooks`, but that can be +changed via the `core.hooksPath` configuration variable (see +linkgit:git-config[1]). Before Git invokes a hook, it changes its working directory to either the root of the working tree in a non-bare repository, or to the @@ -655,6 +655,7 @@ extern int shared_repository; extern const char *apply_default_whitespace; extern const char *apply_default_ignorewhitespace; extern const char *git_attributes_file; +extern const char *git_hooks_path; extern int zlib_compression_level; extern int core_compression_level; extern int core_compression_seen; @@ -717,6 +717,9 @@ static int git_default_core_config(const char *var, const char *value) if (!strcmp(var, "core.attributesfile")) return git_config_pathname(&git_attributes_file, var, value); + if (!strcmp(var, "core.hookspath")) + return git_config_pathname(&git_hooks_path, var, value); + if (!strcmp(var, "core.bare")) { is_bare_repository_cfg = git_config_bool(var, value); return 0; diff --git a/environment.c b/environment.c index 6dec9d0403..a14d115023 100644 --- a/environment.c +++ b/environment.c @@ -33,6 +33,7 @@ int shared_repository = PERM_UMASK; const char *apply_default_whitespace; const char *apply_default_ignorewhitespace; const char *git_attributes_file; +const char *git_hooks_path; int zlib_compression_level = Z_BEST_SPEED; int core_compression_level; int core_compression_seen; diff --git a/run-command.c b/run-command.c index c72601056c..aa85cd5c3c 100644 --- a/run-command.c +++ b/run-command.c @@ -815,7 +815,10 @@ const char *find_hook(const char *name) static struct strbuf path = STRBUF_INIT; strbuf_reset(&path); - strbuf_git_path(&path, "hooks/%s", name); + if (git_hooks_path) + strbuf_addf(&path, "%s/%s", git_hooks_path, name); + else + strbuf_git_path(&path, "hooks/%s", name); if (access(path.buf, X_OK) < 0) return NULL; return path.buf; diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh new file mode 100755 index 0000000000..5e3fb3a6af --- /dev/null +++ b/t/t1350-config-hooks-path.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +test_description='Test the core.hooksPath configuration variable' + +. ./test-lib.sh + +test_expect_success 'set up a pre-commit hook in core.hooksPath' ' + mkdir -p .git/custom-hooks .git/hooks && + write_script .git/custom-hooks/pre-commit <<-\EOF && + echo CUSTOM >>actual + EOF + write_script .git/hooks/pre-commit <<-\EOF + echo NORMAL >>actual + EOF +' + +test_expect_success 'Check that various forms of specifying core.hooksPath work' ' + test_commit no_custom_hook && + git config core.hooksPath .git/custom-hooks && + test_commit have_custom_hook && + git config core.hooksPath .git/custom-hooks/ && + test_commit have_custom_hook_trailing_slash && + git config core.hooksPath "$PWD/.git/custom-hooks" && + test_commit have_custom_hook_abs_path && + git config core.hooksPath "$PWD/.git/custom-hooks/" && + test_commit have_custom_hook_abs_path_trailing_slash && + cat >expect <<-\EOF && + NORMAL + CUSTOM + CUSTOM + CUSTOM + CUSTOM + EOF + test_cmp expect actual +' + +test_done |