@@ -9,25 +9,115 @@ SYNOPSIS
99--------
1010[verse]
1111'git hook' run [-- ignore-missing] [-- to-stdin=<path >] <hook-name > [-- <hook-args >]
12+ 'git hook' list [-z] <hook-name >
1213
1314DESCRIPTION
1415-----------
1516
1617A command interface for running git hooks (see linkgit:githooks[5]),
1718for use by other scripted git commands.
1819
20+ This command parses the default configuration files for sets of configs like
21+ so:
22+
23+ [hook "linter"]
24+ event = pre-commit
25+ command = ~/bin/linter --cpp20
26+
27+ In this example, `[hook "linter"]` represents one script - `~/bin/linter
28+ --cpp20` - which can be shared by many repos, and even by many hook events, if
29+ appropriate.
30+
31+ To add an unrelated hook which runs on a different event, for example a
32+ spell-checker for your commit messages, you would write a configuration like so:
33+
34+ [hook "linter"]
35+ event = pre-commit
36+ command = ~/bin/linter --cpp20
37+ [hook "spellcheck"]
38+ event = commit-msg
39+ command = ~/bin/spellchecker
40+
41+ With this config, when you run 'git commit', first `~/bin/linter --cpp20` will
42+ have a chance to check your files to be committed (during the `pre-commit` hook
43+ event`), and then `~/bin/spellchecker` will have a chance to check your commit
44+ message (during the `commit-msg` hook event).
45+
46+ Commands are run in the order Git encounters their associated
47+ `hook.<name>.event` configs during the configuration parse (see
48+ linkgit:git-config[1]). Although multiple `hook.linter.event` configs can be
49+ added, only one `hook.linter.command` event is valid - Git uses "last-one-wins"
50+ to determine which command to run.
51+
52+ So if you wanted your linter to run when you commit as well as when you push,
53+ you would configure it like so:
54+
55+ [hook "linter"]
56+ event = pre-commit
57+ event = pre-push
58+ command = ~/bin/linter --cpp20
59+
60+ With this config, `~/bin/linter --cpp20` would be run by Git before a commit is
61+ generated (during `pre-commit`) as well as before a push is performed (during
62+ `pre-push`).
63+
64+ And if you wanted to run your linter as well as a secret-leak detector during
65+ only the "pre-commit" hook event, you would configure it instead like so:
66+
67+ [hook "linter"]
68+ event = pre-commit
69+ command = ~/bin/linter --cpp20
70+ [hook "no-leaks"]
71+ event = pre-commit
72+ command = ~/bin/leak-detector
73+
74+ With this config, before a commit is generated (during `pre-commit`), Git would
75+ first start `~/bin/linter --cpp20` and second start `~/bin/leak-detector`. It
76+ would evaluate the output of each when deciding whether to proceed with the
77+ commit.
78+
79+ For a full list of hook events which you can set your `hook.<name>.event` to,
80+ and how hooks are invoked during those events, see linkgit:githooks[5].
81+
82+ Git will ignore any `hook.<name>.event` that specifies an event it doesn't
83+ recognize. This is intended so that tools which wrap Git can use the hook
84+ infrastructure to run their own hooks; see "WRAPPERS" for more guidance.
85+
86+ In general, when instructions suggest adding a script to
87+ `.git/hooks/<hook-event>`, you can specify it in the config instead by running:
88+
89+ ----
90+ git config set hook.<some-name>.command <path-to-script>
91+ git config set --append hook.<some-name>.event <hook-event>
92+ ----
93+
94+ This way you can share the script between multiple repos. That is, `cp
95+ ~/my-script.sh ~/project/.git/hooks/pre-commit` would become:
96+
97+ ----
98+ git config set hook.my-script.command ~/my-script.sh
99+ git config set --append hook.my-script.event pre-commit
100+ ----
101+
19102SUBCOMMANDS
20103-----------
21104
22105run::
23- Run the `<hook-name>` hook. See linkgit:githooks[5] for
24- supported hook names.
106+ Runs hooks configured for `<hook-name>`, in the order they are
107+ discovered during the config parse. The default `<hook-name>` from
108+ the hookdir is run last. See linkgit:githooks[5] for supported
109+ hook names.
25110+
26111
27112Any positional arguments to the hook should be passed after a
28113mandatory `--` (or `--end-of-options`, see linkgit:gitcli[7]). See
29114linkgit:githooks[5] for arguments hooks might expect (if any).
30115
116+ list [-z]::
117+ Print a list of hooks which will be run on `<hook-name>` event. If no
118+ hooks are configured for that event, print a warning and return 1.
119+ Use `-z` to terminate output lines with NUL instead of newlines.
120+
31121OPTIONS
32122-------
33123
@@ -41,6 +131,49 @@ OPTIONS
41131 tools that want to do a blind one-shot run of a hook that may
42132 or may not be present.
43133
134+ -z::
135+ Terminate "list" output lines with NUL instead of newlines.
136+
137+ WRAPPERS
138+ --------
139+
140+ `git hook run` has been designed to make it easy for tools which wrap Git to
141+ configure and execute hooks using the Git hook infrastructure. It is possible to
142+ provide arguments and stdin via the command line, as well as specifying parallel
143+ or series execution if the user has provided multiple hooks.
144+
145+ Assuming your wrapper wants to support a hook named "mywrapper-start-tests", you
146+ can have your users specify their hooks like so:
147+
148+ [hook "setup-test-dashboard"]
149+ event = mywrapper-start-tests
150+ command = ~/mywrapper/setup-dashboard.py --tap
151+
152+ Then, in your 'mywrapper' tool, you can invoke any users' configured hooks by
153+ running:
154+
155+ ----
156+ git hook run mywrapper-start-tests \
157+ # providing something to stdin
158+ --stdin some-tempfile-123 \
159+ # execute hooks in serial
160+ # plus some arguments of your own...
161+ -- \
162+ --testname bar \
163+ baz
164+ ----
165+
166+ Take care to name your wrapper's hook events in a way which is unlikely to
167+ overlap with Git's native hooks (see linkgit:githooks[5]) - a hook event named
168+ `mywrappertool-validate-commit` is much less likely to be added to native Git
169+ than a hook event named `validate-commit`. If Git begins to use a hook event
170+ named the same thing as your wrapper hook, it may invoke your users' hooks in
171+ unintended and unsupported ways.
172+
173+ CONFIGURATION
174+ -------------
175+ include::config/hook.adoc[]
176+
44177SEE ALSO
45178--------
46179linkgit:githooks[5]
0 commit comments