Skip to content

Commit 6675f50

Browse files
committed
Merge branch 'ab/hooks'
A new configuration variable core.hooksPath allows customizing where the hook directory is. * ab/hooks: hooks: allow customizing where the hook directory is githooks.txt: minor improvements to the grammar & phrasing githooks.txt: amend dangerous advice about 'update' hook ACL githooks.txt: improve the intro section
2 parents f2c96ce + 867ad08 commit 6675f50

File tree

8 files changed

+112
-32
lines changed

8 files changed

+112
-32
lines changed

Documentation/config.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,23 @@ core.attributesFile::
618618
$XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME is either not
619619
set or empty, $HOME/.config/git/attributes is used instead.
620620

621+
core.hooksPath::
622+
By default Git will look for your hooks in the
623+
'$GIT_DIR/hooks' directory. Set this to different path,
624+
e.g. '/etc/git/hooks', and Git will try to find your hooks in
625+
that directory, e.g. '/etc/git/hooks/pre-receive' instead of
626+
in '$GIT_DIR/hooks/pre-receive'.
627+
+
628+
The path can be either absolute or relative. A relative path is
629+
taken as relative to the directory where the hooks are run (see
630+
the "DESCRIPTION" section of linkgit:githooks[5]).
631+
+
632+
This configuration variable is useful in cases where you'd like to
633+
centrally configure your Git hooks instead of configuring them on a
634+
per-repository basis, or as a more flexible and centralized
635+
alternative to having an `init.templateDir` where you've changed
636+
default hooks.
637+
621638
core.editor::
622639
Commands such as `commit` and `tag` that lets you edit
623640
messages by launching an editor uses the value of this

Documentation/git-init.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,12 @@ The template directory will be one of the following (in order):
130130
- the default template directory: `/usr/share/git-core/templates`.
131131

132132
The default template directory includes some directory structure, suggested
133-
"exclude patterns" (see linkgit:gitignore[5]), and sample hook files (see linkgit:githooks[5]).
133+
"exclude patterns" (see linkgit:gitignore[5]), and sample hook files.
134+
135+
The sample hooks are all disabled by default, To enable one of the
136+
sample hooks rename it by removing its `.sample` suffix.
137+
138+
See linkgit:githooks[5] for more general info on hook execution.
134139

135140
EXAMPLES
136141
--------

Documentation/githooks.txt

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,51 @@ githooks - Hooks used by Git
77

88
SYNOPSIS
99
--------
10-
$GIT_DIR/hooks/*
10+
$GIT_DIR/hooks/* (or \`git config core.hooksPath`/*)
1111

1212

1313
DESCRIPTION
1414
-----------
1515

16-
Hooks are little scripts you can place in `$GIT_DIR/hooks`
17-
directory to trigger action at certain points. When
18-
'git init' is run, a handful of example hooks are copied into the
19-
`hooks` directory of the new repository, but by default they are
20-
all disabled. To enable a hook, rename it by removing its `.sample`
21-
suffix.
16+
Hooks are programs you can place in a hooks directory to trigger
17+
actions at certain points in git's execution. Hooks that don't have
18+
the executable bit set are ignored.
2219

23-
NOTE: It is also a requirement for a given hook to be executable.
24-
However - in a freshly initialized repository - the `.sample` files are
25-
executable by default.
20+
By default the hooks directory is `$GIT_DIR/hooks`, but that can be
21+
changed via the `core.hooksPath` configuration variable (see
22+
linkgit:git-config[1]).
2623

27-
This document describes the currently defined hooks.
24+
Before Git invokes a hook, it changes its working directory to either
25+
the root of the working tree in a non-bare repository, or to the
26+
$GIT_DIR in a bare repository.
27+
28+
Hooks can get their arguments via the environment, command-line
29+
arguments, and stdin. See the documentation for each hook below for
30+
details.
31+
32+
'git init' may copy hooks to the new repository, depending on its
33+
configuration. See the "TEMPLATE DIRECTORY" section in
34+
linkgit:git-init[1] for details. When the rest of this document refers
35+
to "default hooks" it's talking about the default template shipped
36+
with Git.
37+
38+
The currently supported hooks are described below.
2839

2940
HOOKS
3041
-----
3142

3243
applypatch-msg
3344
~~~~~~~~~~~~~~
3445

35-
This hook is invoked by 'git am' script. It takes a single
46+
This hook is invoked by 'git am'. It takes a single
3647
parameter, the name of the file that holds the proposed commit
37-
log message. Exiting with non-zero status causes
38-
'git am' to abort before applying the patch.
48+
log message. Exiting with a non-zero status causes 'git am' to abort
49+
before applying the patch.
3950

4051
The hook is allowed to edit the message file in place, and can
4152
be used to normalize the message into some project standard
42-
format (if the project has one). It can also be used to refuse
43-
the commit after inspecting the message file.
53+
format. It can also be used to refuse the commit after inspecting
54+
the message file.
4455

4556
The default 'applypatch-msg' hook, when enabled, runs the
4657
'commit-msg' hook, if the latter is enabled.
@@ -73,10 +84,10 @@ pre-commit
7384
~~~~~~~~~~
7485

7586
This hook is invoked by 'git commit', and can be bypassed
76-
with `--no-verify` option. It takes no parameter, and is
87+
with the `--no-verify` option. It takes no parameters, and is
7788
invoked before obtaining the proposed commit log message and
78-
making a commit. Exiting with non-zero status from this script
79-
causes the 'git commit' to abort.
89+
making a commit. Exiting with a non-zero status from this script
90+
causes the 'git commit' command to abort before creating a commit.
8091

8192
The default 'pre-commit' hook, when enabled, catches introduction
8293
of lines with trailing whitespaces and aborts the commit when
@@ -115,24 +126,24 @@ commit-msg
115126
~~~~~~~~~~
116127

117128
This hook is invoked by 'git commit', and can be bypassed
118-
with `--no-verify` option. It takes a single parameter, the
129+
with the `--no-verify` option. It takes a single parameter, the
119130
name of the file that holds the proposed commit log message.
120-
Exiting with non-zero status causes the 'git commit' to
131+
Exiting with a non-zero status causes the 'git commit' to
121132
abort.
122133

123-
The hook is allowed to edit the message file in place, and can
124-
be used to normalize the message into some project standard
125-
format (if the project has one). It can also be used to refuse
126-
the commit after inspecting the message file.
134+
The hook is allowed to edit the message file in place, and can be used
135+
to normalize the message into some project standard format. It
136+
can also be used to refuse the commit after inspecting the message
137+
file.
127138

128139
The default 'commit-msg' hook, when enabled, detects duplicate
129140
"Signed-off-by" lines, and aborts the commit if one is found.
130141

131142
post-commit
132143
~~~~~~~~~~~
133144

134-
This hook is invoked by 'git commit'. It takes no
135-
parameter, and is invoked after a commit is made.
145+
This hook is invoked by 'git commit'. It takes no parameters, and is
146+
invoked after a commit is made.
136147

137148
This hook is meant primarily for notification, and cannot affect
138149
the outcome of 'git commit'.
@@ -267,9 +278,11 @@ does not know the entire set of branches, so it would end up
267278
firing one e-mail per ref when used naively, though. The
268279
<<post-receive,'post-receive'>> hook is more suited to that.
269280

270-
Another use suggested on the mailing list is to use this hook to
271-
implement access control which is finer grained than the one
272-
based on filesystem group.
281+
In an environment that restricts the users' access only to git
282+
commands over the wire, this hook can be used to implement access
283+
control without relying on filesystem ownership and group
284+
membership. See linkgit:git-shell[1] for how you might use the login
285+
shell to restrict the user's access to only git commands.
273286

274287
Both standard output and standard error output are forwarded to
275288
'git send-pack' on the other end, so you can simply `echo` messages

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ extern int warn_on_object_refname_ambiguity;
654654
extern const char *apply_default_whitespace;
655655
extern const char *apply_default_ignorewhitespace;
656656
extern const char *git_attributes_file;
657+
extern const char *git_hooks_path;
657658
extern int zlib_compression_level;
658659
extern int core_compression_level;
659660
extern int core_compression_seen;

config.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,9 @@ static int git_default_core_config(const char *var, const char *value)
717717
if (!strcmp(var, "core.attributesfile"))
718718
return git_config_pathname(&git_attributes_file, var, value);
719719

720+
if (!strcmp(var, "core.hookspath"))
721+
return git_config_pathname(&git_hooks_path, var, value);
722+
720723
if (!strcmp(var, "core.bare")) {
721724
is_bare_repository_cfg = git_config_bool(var, value);
722725
return 0;

environment.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const char *git_log_output_encoding;
3131
const char *apply_default_whitespace;
3232
const char *apply_default_ignorewhitespace;
3333
const char *git_attributes_file;
34+
const char *git_hooks_path;
3435
int zlib_compression_level = Z_BEST_SPEED;
3536
int core_compression_level;
3637
int core_compression_seen;

run-command.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,10 @@ const char *find_hook(const char *name)
825825
static struct strbuf path = STRBUF_INIT;
826826

827827
strbuf_reset(&path);
828-
strbuf_git_path(&path, "hooks/%s", name);
828+
if (git_hooks_path)
829+
strbuf_addf(&path, "%s/%s", git_hooks_path, name);
830+
else
831+
strbuf_git_path(&path, "hooks/%s", name);
829832
if (access(path.buf, X_OK) < 0)
830833
return NULL;
831834
return path.buf;

t/t1350-config-hooks-path.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/sh
2+
3+
test_description='Test the core.hooksPath configuration variable'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'set up a pre-commit hook in core.hooksPath' '
8+
mkdir -p .git/custom-hooks .git/hooks &&
9+
write_script .git/custom-hooks/pre-commit <<-\EOF &&
10+
echo CUSTOM >>actual
11+
EOF
12+
write_script .git/hooks/pre-commit <<-\EOF
13+
echo NORMAL >>actual
14+
EOF
15+
'
16+
17+
test_expect_success 'Check that various forms of specifying core.hooksPath work' '
18+
test_commit no_custom_hook &&
19+
git config core.hooksPath .git/custom-hooks &&
20+
test_commit have_custom_hook &&
21+
git config core.hooksPath .git/custom-hooks/ &&
22+
test_commit have_custom_hook_trailing_slash &&
23+
git config core.hooksPath "$PWD/.git/custom-hooks" &&
24+
test_commit have_custom_hook_abs_path &&
25+
git config core.hooksPath "$PWD/.git/custom-hooks/" &&
26+
test_commit have_custom_hook_abs_path_trailing_slash &&
27+
cat >expect <<-\EOF &&
28+
NORMAL
29+
CUSTOM
30+
CUSTOM
31+
CUSTOM
32+
CUSTOM
33+
EOF
34+
test_cmp expect actual
35+
'
36+
37+
test_done

0 commit comments

Comments
 (0)