mirror of
https://github.com/git/git.git
synced 2026-02-27 18:29:43 +00:00
Teach the hook.[hc] library to parse configs to populate the list of hooks to run for a given event. Multiple commands can be specified for a given hook by providing "hook.<friendly-name>.command = <path-to-hook>" and "hook.<friendly-name>.event = <hook-event>" lines. Hooks will be started in config order of the "hook.<name>.event" lines and will be run sequentially (.jobs == 1) like before. Running the hooks in parallel will be enabled in a future patch. The "traditional" hook from the hookdir is run last, if present. A strmap cache is added to struct repository to avoid re-reading the configs on each rook run. This is useful for hooks like the ref-transaction which gets executed multiple times per process. Examples: $ git config --get-regexp "^hook\." hook.bar.command=~/bar.sh hook.bar.event=pre-commit # Will run ~/bar.sh, then .git/hooks/pre-commit $ git hook run pre-commit Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
180 lines
5.6 KiB
Plaintext
180 lines
5.6 KiB
Plaintext
git-hook(1)
|
|
===========
|
|
|
|
NAME
|
|
----
|
|
git-hook - Run git hooks
|
|
|
|
SYNOPSIS
|
|
--------
|
|
[verse]
|
|
'git hook' run [--ignore-missing] [--to-stdin=<path>] <hook-name> [-- <hook-args>]
|
|
'git hook' list <hook-name>
|
|
|
|
DESCRIPTION
|
|
-----------
|
|
|
|
A command interface for running git hooks (see linkgit:githooks[5]),
|
|
for use by other scripted git commands.
|
|
|
|
This command parses the default configuration files for sets of configs like
|
|
so:
|
|
|
|
[hook "linter"]
|
|
event = pre-commit
|
|
command = ~/bin/linter --cpp20
|
|
|
|
In this example, `[hook "linter"]` represents one script - `~/bin/linter
|
|
--cpp20` - which can be shared by many repos, and even by many hook events, if
|
|
appropriate.
|
|
|
|
To add an unrelated hook which runs on a different event, for example a
|
|
spell-checker for your commit messages, you would write a configuration like so:
|
|
|
|
[hook "linter"]
|
|
event = pre-commit
|
|
command = ~/bin/linter --cpp20
|
|
[hook "spellcheck"]
|
|
event = commit-msg
|
|
command = ~/bin/spellchecker
|
|
|
|
With this config, when you run 'git commit', first `~/bin/linter --cpp20` will
|
|
have a chance to check your files to be committed (during the `pre-commit` hook
|
|
event`), and then `~/bin/spellchecker` will have a chance to check your commit
|
|
message (during the `commit-msg` hook event).
|
|
|
|
Commands are run in the order Git encounters their associated
|
|
`hook.<name>.event` configs during the configuration parse (see
|
|
linkgit:git-config[1]). Although multiple `hook.linter.event` configs can be
|
|
added, only one `hook.linter.command` event is valid - Git uses "last-one-wins"
|
|
to determine which command to run.
|
|
|
|
So if you wanted your linter to run when you commit as well as when you push,
|
|
you would configure it like so:
|
|
|
|
[hook "linter"]
|
|
event = pre-commit
|
|
event = pre-push
|
|
command = ~/bin/linter --cpp20
|
|
|
|
With this config, `~/bin/linter --cpp20` would be run by Git before a commit is
|
|
generated (during `pre-commit`) as well as before a push is performed (during
|
|
`pre-push`).
|
|
|
|
And if you wanted to run your linter as well as a secret-leak detector during
|
|
only the "pre-commit" hook event, you would configure it instead like so:
|
|
|
|
[hook "linter"]
|
|
event = pre-commit
|
|
command = ~/bin/linter --cpp20
|
|
[hook "no-leaks"]
|
|
event = pre-commit
|
|
command = ~/bin/leak-detector
|
|
|
|
With this config, before a commit is generated (during `pre-commit`), Git would
|
|
first start `~/bin/linter --cpp20` and second start `~/bin/leak-detector`. It
|
|
would evaluate the output of each when deciding whether to proceed with the
|
|
commit.
|
|
|
|
For a full list of hook events which you can set your `hook.<name>.event` to,
|
|
and how hooks are invoked during those events, see linkgit:githooks[5].
|
|
|
|
Git will ignore any `hook.<name>.event` that specifies an event it doesn't
|
|
recognize. This is intended so that tools which wrap Git can use the hook
|
|
infrastructure to run their own hooks; see "WRAPPERS" for more guidance.
|
|
|
|
In general, when instructions suggest adding a script to
|
|
`.git/hooks/<hook-event>`, you can specify it in the config instead by running:
|
|
|
|
----
|
|
git config set hook.<some-name>.command <path-to-script>
|
|
git config set --append hook.<some-name>.event <hook-event>
|
|
----
|
|
|
|
This way you can share the script between multiple repos. That is, `cp
|
|
~/my-script.sh ~/project/.git/hooks/pre-commit` would become:
|
|
|
|
----
|
|
git config set hook.my-script.command ~/my-script.sh
|
|
git config set --append hook.my-script.event pre-commit
|
|
----
|
|
|
|
SUBCOMMANDS
|
|
-----------
|
|
|
|
run::
|
|
Runs hooks configured for `<hook-name>`, in the order they are
|
|
discovered during the config parse. The default `<hook-name>` from
|
|
the hookdir is run last. See linkgit:githooks[5] for supported
|
|
hook names.
|
|
+
|
|
|
|
Any positional arguments to the hook should be passed after a
|
|
mandatory `--` (or `--end-of-options`, see linkgit:gitcli[7]). See
|
|
linkgit:githooks[5] for arguments hooks might expect (if any).
|
|
|
|
list::
|
|
Print a list of hooks which will be run on `<hook-name>` event. If no
|
|
hooks are configured for that event, print a warning and return 1.
|
|
|
|
OPTIONS
|
|
-------
|
|
|
|
--to-stdin::
|
|
For "run"; specify a file which will be streamed into the
|
|
hook's stdin. The hook will receive the entire file from
|
|
beginning to EOF.
|
|
|
|
--ignore-missing::
|
|
Ignore any missing hook by quietly returning zero. Used for
|
|
tools that want to do a blind one-shot run of a hook that may
|
|
or may not be present.
|
|
|
|
WRAPPERS
|
|
--------
|
|
|
|
`git hook run` has been designed to make it easy for tools which wrap Git to
|
|
configure and execute hooks using the Git hook infrastructure. It is possible to
|
|
provide arguments and stdin via the command line, as well as specifying parallel
|
|
or series execution if the user has provided multiple hooks.
|
|
|
|
Assuming your wrapper wants to support a hook named "mywrapper-start-tests", you
|
|
can have your users specify their hooks like so:
|
|
|
|
[hook "setup-test-dashboard"]
|
|
event = mywrapper-start-tests
|
|
command = ~/mywrapper/setup-dashboard.py --tap
|
|
|
|
Then, in your 'mywrapper' tool, you can invoke any users' configured hooks by
|
|
running:
|
|
|
|
----
|
|
git hook run mywrapper-start-tests \
|
|
# providing something to stdin
|
|
--stdin some-tempfile-123 \
|
|
# execute hooks in serial
|
|
# plus some arguments of your own...
|
|
-- \
|
|
--testname bar \
|
|
baz
|
|
----
|
|
|
|
Take care to name your wrapper's hook events in a way which is unlikely to
|
|
overlap with Git's native hooks (see linkgit:githooks[5]) - a hook event named
|
|
`mywrappertool-validate-commit` is much less likely to be added to native Git
|
|
than a hook event named `validate-commit`. If Git begins to use a hook event
|
|
named the same thing as your wrapper hook, it may invoke your users' hooks in
|
|
unintended and unsupported ways.
|
|
|
|
CONFIGURATION
|
|
-------------
|
|
include::config/hook.adoc[]
|
|
|
|
SEE ALSO
|
|
--------
|
|
linkgit:githooks[5]
|
|
|
|
GIT
|
|
---
|
|
Part of the linkgit:git[1] suite
|