2008-05-02 03:30:47 +00:00
|
|
|
githooks(5)
|
|
|
|
===========
|
|
|
|
|
|
|
|
NAME
|
|
|
|
----
|
2013-01-21 19:17:53 +00:00
|
|
|
githooks - Hooks used by Git
|
2008-05-02 03:30:47 +00:00
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
--------
|
2016-05-04 22:58:12 +00:00
|
|
|
$GIT_DIR/hooks/* (or \`git config core.hooksPath`/*)
|
2008-05-02 03:30:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
-----------
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2016-05-04 22:58:12 +00:00
|
|
|
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]).
|
2016-05-04 22:58:09 +00:00
|
|
|
|
|
|
|
Before Git invokes a hook, it changes its working directory to either
|
2017-04-29 12:28:29 +00:00
|
|
|
$GIT_DIR in a bare repository or the root of the working tree in a non-bare
|
|
|
|
repository. An exception are hooks triggered during a push ('pre-receive',
|
|
|
|
'update', 'post-receive', 'post-update', 'push-to-checkout') which are always
|
|
|
|
executed in $GIT_DIR.
|
2016-05-04 22:58:09 +00:00
|
|
|
|
githooks: discuss Git operations in foreign repositories
Hook authors are periodically caught off-guard by difficult-to-diagnose
errors when their hook invokes Git commands in a repository other than
the local one. In particular, Git environment variables, such as GIT_DIR
and GIT_WORK_TREE, which reference the local repository cause the Git
commands to operate on the local repository rather than on the
repository which the author intended. This is true whether the
environment variables have been set manually by the user or
automatically by Git itself. The same problem crops up when a hook
invokes Git commands in a different worktree of the same repository, as
well.
Recommended best-practice[1,2,3,4,5,6] for avoiding this problem is for
the hook to ensure that Git variables are unset before invoking Git
commands in foreign repositories or other worktrees:
unset $(git rev-parse --local-env-vars)
However, this advice is not documented anywhere. Rectify this
shortcoming by mentioning it in githooks.txt documentation.
[1]: https://lore.kernel.org/git/YFuHd1MMlJAvtdzb@coredump.intra.peff.net/
[2]: https://lore.kernel.org/git/20200228190218.GC1408759@coredump.intra.peff.net/
[3]: https://lore.kernel.org/git/20190516221702.GA11784@sigill.intra.peff.net/
[4]: https://lore.kernel.org/git/20190422162127.GC9680@sigill.intra.peff.net/
[5]: https://lore.kernel.org/git/20180716183942.GB22298@sigill.intra.peff.net/
[6]: https://lore.kernel.org/git/20150203163235.GA9325@peff.net/
Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-01-09 19:45:08 +00:00
|
|
|
Environment variables, such as `GIT_DIR`, `GIT_WORK_TREE`, etc., are exported
|
|
|
|
so that Git commands run by the hook can correctly locate the repository. If
|
|
|
|
your hook needs to invoke Git commands in a foreign repository or in a
|
|
|
|
different working tree of the same repository, then it should clear these
|
|
|
|
environment variables so they do not interfere with Git operations at the
|
|
|
|
foreign location. For example:
|
|
|
|
|
|
|
|
------------
|
|
|
|
local_desc=$(git describe)
|
|
|
|
foreign_desc=$(unset $(git rev-parse --local-env-vars); git -C ../foreign-repo describe)
|
|
|
|
------------
|
|
|
|
|
2016-05-04 22:58:09 +00:00
|
|
|
Hooks can get their arguments via the environment, command-line
|
|
|
|
arguments, and stdin. See the documentation for each hook below for
|
|
|
|
details.
|
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
`git init` may copy hooks to the new repository, depending on its
|
2016-05-04 22:58:09 +00:00
|
|
|
configuration. See the "TEMPLATE DIRECTORY" section in
|
|
|
|
linkgit:git-init[1] for details. When the rest of this document refers
|
|
|
|
to "default hooks" it's talking about the default template shipped
|
|
|
|
with Git.
|
|
|
|
|
|
|
|
The currently supported hooks are described below.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2009-09-06 10:22:58 +00:00
|
|
|
HOOKS
|
|
|
|
-----
|
|
|
|
|
2005-09-03 04:19:26 +00:00
|
|
|
applypatch-msg
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~~~~~
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-am[1]. It takes a single
|
2005-09-03 04:19:26 +00:00
|
|
|
parameter, the name of the file that holds the proposed commit
|
2018-05-03 18:48:24 +00:00
|
|
|
log message. Exiting with a non-zero status causes `git am` to abort
|
2016-05-04 22:58:11 +00:00
|
|
|
before applying the patch.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
|
|
|
The hook is allowed to edit the message file in place, and can
|
|
|
|
be used to normalize the message into some project standard
|
2016-05-04 22:58:11 +00:00
|
|
|
format. It can also be used to refuse the commit after inspecting
|
|
|
|
the message file.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2006-09-20 10:15:39 +00:00
|
|
|
The default 'applypatch-msg' hook, when enabled, runs the
|
|
|
|
'commit-msg' hook, if the latter is enabled.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
|
|
|
pre-applypatch
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~~~~~
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-am[1]. It takes no parameter, and is
|
2008-05-02 03:30:41 +00:00
|
|
|
invoked after the patch is applied, but before a commit is made.
|
|
|
|
|
|
|
|
If it exits with non-zero status, then the working tree will not be
|
|
|
|
committed after applying the patch.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
|
|
|
It can be used to inspect the current working tree and refuse to
|
|
|
|
make a commit if it does not pass certain test.
|
|
|
|
|
2006-09-20 10:15:39 +00:00
|
|
|
The default 'pre-applypatch' hook, when enabled, runs the
|
|
|
|
'pre-commit' hook, if the latter is enabled.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
|
|
|
post-applypatch
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~~~~~~
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-am[1]. It takes no parameter,
|
2005-09-03 04:19:26 +00:00
|
|
|
and is invoked after the patch is applied and a commit is made.
|
|
|
|
|
|
|
|
This hook is meant primarily for notification, and cannot affect
|
2018-05-03 18:48:24 +00:00
|
|
|
the outcome of `git am`.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
|
|
|
pre-commit
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-commit[1], and can be bypassed
|
2016-05-04 22:58:11 +00:00
|
|
|
with the `--no-verify` option. It takes no parameters, and is
|
2005-09-03 04:19:26 +00:00
|
|
|
invoked before obtaining the proposed commit log message and
|
2016-05-04 22:58:11 +00:00
|
|
|
making a commit. Exiting with a non-zero status from this script
|
2018-05-03 18:48:24 +00:00
|
|
|
causes the `git commit` command to abort before creating a commit.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2006-09-20 10:15:39 +00:00
|
|
|
The default 'pre-commit' hook, when enabled, catches introduction
|
2005-09-03 04:19:26 +00:00
|
|
|
of lines with trailing whitespaces and aborts the commit when
|
2006-09-20 10:15:39 +00:00
|
|
|
such a line is found.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
All the `git commit` hooks are invoked with the environment
|
2008-02-05 10:01:45 +00:00
|
|
|
variable `GIT_EDITOR=:` if the command will not bring up an editor
|
|
|
|
to modify the commit message.
|
|
|
|
|
2019-02-20 07:53:54 +00:00
|
|
|
The default 'pre-commit' hook, when enabled--and with the
|
|
|
|
`hooks.allownonascii` config option unset or set to false--prevents
|
|
|
|
the use of non-ASCII filenames.
|
|
|
|
|
2019-08-07 18:57:07 +00:00
|
|
|
pre-merge-commit
|
|
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
|
2019-08-07 18:57:08 +00:00
|
|
|
This hook is invoked by linkgit:git-merge[1], and can be bypassed
|
|
|
|
with the `--no-verify` option. It takes no parameters, and is
|
2019-08-07 18:57:07 +00:00
|
|
|
invoked after the merge has been carried out successfully and before
|
|
|
|
obtaining the proposed commit log message to
|
|
|
|
make a commit. Exiting with a non-zero status from this script
|
|
|
|
causes the `git merge` command to abort before creating a commit.
|
|
|
|
|
|
|
|
The default 'pre-merge-commit' hook, when enabled, runs the
|
|
|
|
'pre-commit' hook, if the latter is enabled.
|
|
|
|
|
|
|
|
This hook is invoked with the environment variable
|
|
|
|
`GIT_EDITOR=:` if the command will not bring up an editor
|
|
|
|
to modify the commit message.
|
|
|
|
|
|
|
|
If the merge cannot be carried out automatically, the conflicts
|
|
|
|
need to be resolved and the result committed separately (see
|
|
|
|
linkgit:git-merge[1]). At that point, this hook will not be executed,
|
|
|
|
but the 'pre-commit' hook will, if it is enabled.
|
|
|
|
|
2008-02-05 07:04:18 +00:00
|
|
|
prepare-commit-msg
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~~~~~~~~~
|
2008-02-05 07:04:18 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-commit[1] right after preparing the
|
2008-02-05 07:04:18 +00:00
|
|
|
default log message, and before the editor is started.
|
|
|
|
|
|
|
|
It takes one to three parameters. The first is the name of the file
|
2009-01-16 20:36:06 +00:00
|
|
|
that contains the commit log message. The second is the source of the commit
|
2008-09-30 17:27:10 +00:00
|
|
|
message, and can be: `message` (if a `-m` or `-F` option was
|
|
|
|
given); `template` (if a `-t` option was given or the
|
2008-02-05 07:04:18 +00:00
|
|
|
configuration option `commit.template` is set); `merge` (if the
|
|
|
|
commit is a merge or a `.git/MERGE_MSG` file exists); `squash`
|
|
|
|
(if a `.git/SQUASH_MSG` file exists); or `commit`, followed by
|
2021-03-01 09:43:47 +00:00
|
|
|
a commit object name (if a `-c`, `-C` or `--amend` option was given).
|
2008-02-05 07:04:18 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
If the exit status is non-zero, `git commit` will abort.
|
2008-02-05 07:04:18 +00:00
|
|
|
|
|
|
|
The purpose of the hook is to edit the message file in place, and
|
docs: stop using asciidoc no-inline-literal
In asciidoc 7, backticks like `foo` produced a typographic
effect, but did not otherwise affect the syntax. In asciidoc
8, backticks introduce an "inline literal" inside which markup
is not interpreted. To keep compatibility with existing
documents, asciidoc 8 has a "no-inline-literal" attribute to
keep the old behavior. We enabled this so that the
documentation could be built on either version.
It has been several years now, and asciidoc 7 is no longer
in wide use. We can now decide whether or not we want
inline literals on their own merits, which are:
1. The source is much easier to read when the literal
contains punctuation. You can use `master~1` instead
of `master{tilde}1`.
2. They are less error-prone. Because of point (1), we
tend to make mistakes and forget the extra layer of
quoting.
This patch removes the no-inline-literal attribute from the
Makefile and converts every use of backticks in the
documentation to an inline literal (they must be cleaned up,
or the example above would literally show "{tilde}" in the
output).
Problematic sites were found by grepping for '`.*[{\\]' and
examined and fixed manually. The results were then verified
by comparing the output of "html2text" on the set of
generated html pages. Doing so revealed that in addition to
making the source more readable, this patch fixes several
formatting bugs:
- HTML rendering used the ellipsis character instead of
literal "..." in code examples (like "git log A...B")
- some code examples used the right-arrow character
instead of '->' because they failed to quote
- api-config.txt did not quote tilde, and the resulting
HTML contained a bogus snippet like:
<tt><sub></tt> foo <tt></sub>bar</tt>
which caused some parsers to choke and omit whole
sections of the page.
- git-commit.txt confused ``foo`` (backticks inside a
literal) with ``foo'' (matched double-quotes)
- mentions of `A U Thor <author@example.com>` used to
erroneously auto-generate a mailto footnote for
author@example.com
- the description of --word-diff=plain incorrectly showed
the output as "[-removed-] and {added}", not "{+added+}".
- using "prime" notation like:
commit `C` and its replacement `C'`
confused asciidoc into thinking that everything between
the first backtick and the final apostrophe were meant
to be inside matched quotes
- asciidoc got confused by the escaping of some of our
asterisks. In particular,
`credential.\*` and `credential.<url>.\*`
properly escaped the asterisk in the first case, but
literally passed through the backslash in the second
case.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-26 08:51:57 +00:00
|
|
|
it is not suppressed by the `--no-verify` option. A non-zero exit
|
2008-02-05 07:04:18 +00:00
|
|
|
means a failure of the hook and aborts the commit. It should not
|
|
|
|
be used as replacement for pre-commit hook.
|
|
|
|
|
2017-07-11 14:30:54 +00:00
|
|
|
The sample `prepare-commit-msg` hook that comes with Git removes the
|
|
|
|
help message found in the commented portion of the commit template.
|
|
|
|
|
2005-09-03 04:19:26 +00:00
|
|
|
commit-msg
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-commit[1] and linkgit:git-merge[1], and can be
|
2017-09-21 20:29:54 +00:00
|
|
|
bypassed with the `--no-verify` option. It takes a single parameter,
|
|
|
|
the name of the file that holds the proposed commit log message.
|
|
|
|
Exiting with a non-zero status causes the command to abort.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2016-05-04 22:58:11 +00:00
|
|
|
The hook is allowed to edit the message file in place, and can be used
|
|
|
|
to normalize the message into some project standard format. It
|
|
|
|
can also be used to refuse the commit after inspecting the message
|
|
|
|
file.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2006-09-20 10:15:39 +00:00
|
|
|
The default 'commit-msg' hook, when enabled, detects duplicate
|
Documentation: stylistically normalize references to Signed-off-by:
Ted reported an old typo in the git-commit.txt and merge-options.txt.
Namely, the phrase "Signed-off-by line" was used without either a
definite nor indefinite article.
Upon examination, it seems that the documentation (including items in
Documentation/, but also option help strings) have been quite
inconsistent on usage when referring to `Signed-off-by`.
First, very few places used a definite or indefinite article with the
phrase "Signed-off-by line", but that was the initial typo that led
to this investigation. So, normalize using either an indefinite or
definite article consistently.
The original phrasing, in Commit 3f971fc425b (Documentation updates,
2005-08-14), is "Add Signed-off-by line". Commit 6f855371a53 (Add
--signoff, --check, and long option-names. 2005-12-09) switched to
using "Add `Signed-off-by:` line", but didn't normalize the former
commit to match. Later commits seem to have cut and pasted from one
or the other, which is likely how the usage became so inconsistent.
Junio stated on the git mailing list in
<xmqqy2k1dfoh.fsf@gitster.c.googlers.com> a preference to leave off
the colon. Thus, prefer `Signed-off-by` (with backticks) for the
documentation files and Signed-off-by (without backticks) for option
help strings.
Additionally, Junio argued that "trailer" is now the standard term to
refer to `Signed-off-by`, saying that "becomes plenty clear that we
are not talking about any random line in the log message". As such,
prefer "trailer" over "line" anywhere the former word fits.
However, leave alone those few places in documentation that use
Signed-off-by to refer to the process (rather than the specific
trailer), or in places where mail headers are generally discussed in
comparison with Signed-off-by.
Reported-by: "Theodore Y. Ts'o" <tytso@mit.edu>
Signed-off-by: Bradley M. Kuhn <bkuhn@sfconservancy.org>
Acked-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-20 01:03:55 +00:00
|
|
|
`Signed-off-by` trailers, and aborts the commit if one is found.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
|
|
|
post-commit
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~~
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-commit[1]. It takes no parameters, and is
|
2016-05-04 22:58:11 +00:00
|
|
|
invoked after a commit is made.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
|
|
|
This hook is meant primarily for notification, and cannot affect
|
2018-05-03 18:48:24 +00:00
|
|
|
the outcome of `git commit`.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2008-10-05 13:26:54 +00:00
|
|
|
pre-rebase
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~
|
2008-10-05 13:26:54 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is called by linkgit:git-rebase[1] and can be used to prevent a
|
2013-02-23 15:27:39 +00:00
|
|
|
branch from getting rebased. The hook may be called with one or
|
|
|
|
two parameters. The first parameter is the upstream from which
|
|
|
|
the series was forked. The second parameter is the branch being
|
|
|
|
rebased, and is not set when rebasing the current branch.
|
2008-10-05 13:26:54 +00:00
|
|
|
|
2007-09-26 21:31:01 +00:00
|
|
|
post-checkout
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~~~~
|
2007-09-26 21:31:01 +00:00
|
|
|
|
2019-03-29 10:39:05 +00:00
|
|
|
This hook is invoked when a linkgit:git-checkout[1] or
|
|
|
|
linkgit:git-switch[1] is run after having updated the
|
2007-09-26 21:31:01 +00:00
|
|
|
worktree. The hook is given three parameters: the ref of the previous HEAD,
|
|
|
|
the ref of the new HEAD (which may or may not have changed), and a flag
|
|
|
|
indicating whether the checkout was a branch checkout (changing branches,
|
|
|
|
flag=1) or a file checkout (retrieving a file from the index, flag=0).
|
2020-08-27 21:45:11 +00:00
|
|
|
This hook cannot affect the outcome of `git switch` or `git checkout`,
|
|
|
|
other than that the hook's exit status becomes the exit status of
|
|
|
|
these two commands.
|
2007-09-26 21:31:01 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
It is also run after linkgit:git-clone[1], unless the `--no-checkout` (`-n`) option is
|
2009-03-22 18:46:38 +00:00
|
|
|
used. The first parameter given to the hook is the null-ref, the second the
|
2018-05-03 18:48:24 +00:00
|
|
|
ref of the new HEAD and the flag is always 1. Likewise for `git worktree add`
|
|
|
|
unless `--no-checkout` is used.
|
2009-03-22 18:46:38 +00:00
|
|
|
|
2007-09-26 21:31:01 +00:00
|
|
|
This hook can be used to perform repository validity checks, auto-display
|
|
|
|
differences from the previous HEAD if different, or set working dir metadata
|
|
|
|
properties.
|
|
|
|
|
2007-09-11 16:59:03 +00:00
|
|
|
post-merge
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~
|
2007-09-11 16:59:03 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-merge[1], which happens when a `git pull`
|
2007-09-11 16:59:03 +00:00
|
|
|
is done on a local repository. The hook takes a single parameter, a status
|
|
|
|
flag specifying whether or not the merge being done was a squash merge.
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook cannot affect the outcome of `git merge` and is not executed,
|
2008-05-05 09:06:49 +00:00
|
|
|
if the merge failed due to conflicts.
|
2007-09-11 16:59:03 +00:00
|
|
|
|
|
|
|
This hook can be used in conjunction with a corresponding pre-commit hook to
|
|
|
|
save and restore any form of metadata associated with the working tree
|
2014-11-03 20:37:07 +00:00
|
|
|
(e.g.: permissions/ownership, ACLS, etc). See contrib/hooks/setgitperms.perl
|
2007-09-11 16:59:04 +00:00
|
|
|
for an example of how to do this.
|
2007-09-11 16:59:03 +00:00
|
|
|
|
2013-01-13 05:17:03 +00:00
|
|
|
pre-push
|
|
|
|
~~~~~~~~
|
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is called by linkgit:git-push[1] and can be used to prevent
|
|
|
|
a push from taking place. The hook is called with two parameters
|
|
|
|
which provide the name and location of the destination remote, if a
|
|
|
|
named remote is not being used both values will be the same.
|
2013-01-13 05:17:03 +00:00
|
|
|
|
|
|
|
Information about what is to be pushed is provided on the hook's standard
|
|
|
|
input with lines of the form:
|
|
|
|
|
2021-03-01 09:43:47 +00:00
|
|
|
<local ref> SP <local object name> SP <remote ref> SP <remote object name> LF
|
2013-01-13 05:17:03 +00:00
|
|
|
|
|
|
|
For instance, if the command +git push origin master:foreign+ were run the
|
|
|
|
hook would receive a line like the following:
|
|
|
|
|
|
|
|
refs/heads/master 67890 refs/heads/foreign 12345
|
|
|
|
|
2021-03-01 09:43:47 +00:00
|
|
|
although the full object name would be supplied. If the foreign ref does not
|
|
|
|
yet exist the `<remote object name>` will be the all-zeroes object name. If a
|
|
|
|
ref is to be deleted, the `<local ref>` will be supplied as `(delete)` and the
|
|
|
|
`<local object name>` will be the all-zeroes object name. If the local commit
|
|
|
|
was specified by something other than a name which could be expanded (such as
|
|
|
|
`HEAD~`, or an object name) it will be supplied as it was originally given.
|
2013-01-13 05:17:03 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
If this hook exits with a non-zero status, `git push` will abort without
|
2013-01-13 05:17:03 +00:00
|
|
|
pushing anything. Information about why the push is rejected may be sent
|
|
|
|
to the user by writing to standard error.
|
|
|
|
|
2007-05-12 17:11:13 +00:00
|
|
|
[[pre-receive]]
|
|
|
|
pre-receive
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~~
|
2007-05-12 17:11:13 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
|
|
|
|
`git push` and updates reference(s) in its repository.
|
2007-05-12 17:11:13 +00:00
|
|
|
Just before starting to update refs on the remote repository, the
|
|
|
|
pre-receive hook is invoked. Its exit status determines the success
|
|
|
|
or failure of the update.
|
|
|
|
|
|
|
|
This hook executes once for the receive operation. It takes no
|
|
|
|
arguments, but for each ref to be updated it receives on standard
|
|
|
|
input a line of the format:
|
|
|
|
|
|
|
|
<old-value> SP <new-value> SP <ref-name> LF
|
|
|
|
|
|
|
|
where `<old-value>` is the old object name stored in the ref,
|
|
|
|
`<new-value>` is the new object name to be stored in the ref and
|
|
|
|
`<ref-name>` is the full name of the ref.
|
2021-03-01 09:43:47 +00:00
|
|
|
When creating a new ref, `<old-value>` is the all-zeroes object name.
|
2007-05-12 17:11:13 +00:00
|
|
|
|
|
|
|
If the hook exits with non-zero status, none of the refs will be
|
|
|
|
updated. If the hook exits with zero, updating of individual refs can
|
|
|
|
still be prevented by the <<update,'update'>> hook.
|
|
|
|
|
2007-05-12 21:43:11 +00:00
|
|
|
Both standard output and standard error output are forwarded to
|
2018-05-03 18:48:24 +00:00
|
|
|
`git send-pack` on the other end, so you can simply `echo` messages
|
2007-05-12 21:43:11 +00:00
|
|
|
for the user.
|
2007-05-12 17:11:13 +00:00
|
|
|
|
push options: {pre,post}-receive hook learns about push options
The environment variable GIT_PUSH_OPTION_COUNT is set to the number of
push options sent, and GIT_PUSH_OPTION_{0,1,..} is set to the transmitted
option.
The code is not executed as the push options are set to NULL, nor is the
new capability advertised.
There was some discussion back and forth how to present these push options
to the user as there are some ways to do it:
Keep all options in one environment variable
============================================
+ easiest way to implement in Git
- This would make things hard to parse correctly in the hook.
Put the options in files instead,
filenames are in GIT_PUSH_OPTION_FILES
======================================
+ After a discussion about environment variables and shells, we may not
want to put user data into an environment variable (see [1] for example).
+ We could transmit binaries, i.e. we're not bound to C strings as
we are when using environment variables to the user.
+ Maybe easier to parse than constructing environment variable names
GIT_PUSH_OPTION_{0,1,..} yourself
- cleanup of the temporary files is hard to do reliably
- we have race conditions with multiple clients pushing, hence we'd need
to use mkstemp. That's not too bad, but still.
Use environment variables, but restrict to key/value pairs
==========================================================
(When the user pushes a push option `foo=bar`, we'd
GIT_PUSH_OPTION_foo=bar)
+ very easy to parse for a simple model of push options
- it's not sufficient for more elaborate models, e.g.
it doesn't allow doubles (e.g. cc=reviewer@email)
Present the options in different environment variables
======================================================
(This is implemented)
* harder to parse as a user, but we have a sample hook for that.
- doesn't allow binary files
+ allows the same option twice, i.e. is not restrictive about
options, except for binary files.
+ doesn't clutter a remote directory with (possibly stale)
temporary files
As we first want to focus on getting simple strings to work
reliably, we go with the last option for now. If we want to
do transmission of binaries later, we can just attach a
'side-channel', e.g. "any push option that contains a '\0' is
put into a file instead of the environment variable and we'd
have new GIT_PUSH_OPTION_FILES, GIT_PUSH_OPTION_FILENAME_{0,1,..}
environment variables".
[1] 'Shellshock' https://lwn.net/Articles/614218/
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-14 21:49:45 +00:00
|
|
|
The number of push options given on the command line of
|
|
|
|
`git push --push-option=...` can be read from the environment
|
|
|
|
variable `GIT_PUSH_OPTION_COUNT`, and the options themselves are
|
|
|
|
found in `GIT_PUSH_OPTION_0`, `GIT_PUSH_OPTION_1`,...
|
|
|
|
If it is negotiated to not use the push options phase, the
|
|
|
|
environment variables will not be set. If the client selects
|
|
|
|
to use push options, but doesn't transmit any, the count variable
|
|
|
|
will be set to zero, `GIT_PUSH_OPTION_COUNT=0`.
|
|
|
|
|
2017-04-10 22:13:39 +00:00
|
|
|
See the section on "Quarantine Environment" in
|
|
|
|
linkgit:git-receive-pack[1] for some caveats.
|
|
|
|
|
2007-05-12 17:11:13 +00:00
|
|
|
[[update]]
|
2005-09-03 04:19:26 +00:00
|
|
|
update
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
|
|
|
|
`git push` and updates reference(s) in its repository.
|
2006-03-25 03:21:07 +00:00
|
|
|
Just before updating the ref on the remote repository, the update hook
|
2006-06-07 12:56:45 +00:00
|
|
|
is invoked. Its exit status determines the success or failure of
|
2006-03-25 03:21:07 +00:00
|
|
|
the ref update.
|
|
|
|
|
|
|
|
The hook executes once for each ref to be updated, and takes
|
|
|
|
three parameters:
|
2006-09-20 10:15:39 +00:00
|
|
|
|
|
|
|
- the name of the ref being updated,
|
|
|
|
- the old object name stored in the ref,
|
2014-02-05 22:19:43 +00:00
|
|
|
- and the new object name to be stored in the ref.
|
2006-03-25 03:21:07 +00:00
|
|
|
|
|
|
|
A zero exit from the update hook allows the ref to be updated.
|
2018-05-03 18:48:24 +00:00
|
|
|
Exiting with a non-zero status prevents `git receive-pack`
|
2007-05-12 17:11:13 +00:00
|
|
|
from updating that ref.
|
2006-03-25 03:21:07 +00:00
|
|
|
|
|
|
|
This hook can be used to prevent 'forced' update on certain refs by
|
2005-09-03 04:19:26 +00:00
|
|
|
making sure that the object name is a commit object that is a
|
|
|
|
descendant of the commit object named by the old object name.
|
2009-10-24 08:31:32 +00:00
|
|
|
That is, to enforce a "fast-forward only" policy.
|
2006-03-25 03:21:07 +00:00
|
|
|
|
|
|
|
It could also be used to log the old..new status. However, it
|
|
|
|
does not know the entire set of branches, so it would end up
|
2007-05-12 17:11:13 +00:00
|
|
|
firing one e-mail per ref when used naively, though. The
|
|
|
|
<<post-receive,'post-receive'>> hook is more suited to that.
|
2006-03-25 03:21:07 +00:00
|
|
|
|
2016-05-04 22:58:10 +00:00
|
|
|
In an environment that restricts the users' access only to git
|
|
|
|
commands over the wire, this hook can be used to implement access
|
|
|
|
control without relying on filesystem ownership and group
|
|
|
|
membership. See linkgit:git-shell[1] for how you might use the login
|
|
|
|
shell to restrict the user's access to only git commands.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2007-05-12 21:43:11 +00:00
|
|
|
Both standard output and standard error output are forwarded to
|
2018-05-03 18:48:24 +00:00
|
|
|
`git send-pack` on the other end, so you can simply `echo` messages
|
2007-05-12 21:43:11 +00:00
|
|
|
for the user.
|
2005-12-20 00:35:48 +00:00
|
|
|
|
2007-05-12 17:11:13 +00:00
|
|
|
The default 'update' hook, when enabled--and with
|
2009-09-14 08:47:06 +00:00
|
|
|
`hooks.allowunannotated` config option unset or set to false--prevents
|
2007-05-12 17:11:13 +00:00
|
|
|
unannotated tags to be pushed.
|
|
|
|
|
2020-08-27 15:45:51 +00:00
|
|
|
[[proc-receive]]
|
|
|
|
proc-receive
|
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
|
|
|
This hook is invoked by linkgit:git-receive-pack[1]. If the server has
|
|
|
|
set the multi-valued config variable `receive.procReceiveRefs`, and the
|
|
|
|
commands sent to 'receive-pack' have matching reference names, these
|
|
|
|
commands will be executed by this hook, instead of by the internal
|
|
|
|
`execute_commands()` function. This hook is responsible for updating
|
|
|
|
the relevant references and reporting the results back to 'receive-pack'.
|
|
|
|
|
|
|
|
This hook executes once for the receive operation. It takes no
|
|
|
|
arguments, but uses a pkt-line format protocol to communicate with
|
|
|
|
'receive-pack' to read commands, push-options and send results. In the
|
|
|
|
following example for the protocol, the letter 'S' stands for
|
|
|
|
'receive-pack' and the letter 'H' stands for this hook.
|
|
|
|
|
|
|
|
# Version and features negotiation.
|
|
|
|
S: PKT-LINE(version=1\0push-options atomic...)
|
|
|
|
S: flush-pkt
|
|
|
|
H: PKT-LINE(version=1\0push-options...)
|
|
|
|
H: flush-pkt
|
|
|
|
|
|
|
|
# Send commands from server to the hook.
|
|
|
|
S: PKT-LINE(<old-oid> <new-oid> <ref>)
|
|
|
|
S: ... ...
|
|
|
|
S: flush-pkt
|
|
|
|
# Send push-options only if the 'push-options' feature is enabled.
|
|
|
|
S: PKT-LINE(push-option)
|
|
|
|
S: ... ...
|
|
|
|
S: flush-pkt
|
|
|
|
|
|
|
|
# Receive result from the hook.
|
|
|
|
# OK, run this command successfully.
|
|
|
|
H: PKT-LINE(ok <ref>)
|
|
|
|
# NO, I reject it.
|
|
|
|
H: PKT-LINE(ng <ref> <reason>)
|
|
|
|
# Fall through, let 'receive-pack' to execute it.
|
|
|
|
H: PKT-LINE(ok <ref>)
|
|
|
|
H: PKT-LINE(option fall-through)
|
|
|
|
# OK, but has an alternate reference. The alternate reference name
|
|
|
|
# and other status can be given in option directives.
|
|
|
|
H: PKT-LINE(ok <ref>)
|
|
|
|
H: PKT-LINE(option refname <refname>)
|
|
|
|
H: PKT-LINE(option old-oid <old-oid>)
|
|
|
|
H: PKT-LINE(option new-oid <new-oid>)
|
|
|
|
H: PKT-LINE(option forced-update)
|
|
|
|
H: ... ...
|
|
|
|
H: flush-pkt
|
|
|
|
|
|
|
|
Each command for the 'proc-receive' hook may point to a pseudo-reference
|
|
|
|
and always has a zero-old as its old-oid, while the 'proc-receive' hook
|
|
|
|
may update an alternate reference and the alternate reference may exist
|
|
|
|
already with a non-zero old-oid. For this case, this hook will use
|
|
|
|
"option" directives to report extended attributes for the reference given
|
|
|
|
by the leading "ok" directive.
|
|
|
|
|
|
|
|
The report of the commands of this hook should have the same order as
|
|
|
|
the input. The exit status of the 'proc-receive' hook only determines
|
|
|
|
the success or failure of the group of commands sent to it, unless
|
|
|
|
atomic push is in use.
|
|
|
|
|
2007-05-12 17:11:13 +00:00
|
|
|
[[post-receive]]
|
|
|
|
post-receive
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~~~
|
2006-03-25 03:21:07 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
|
|
|
|
`git push` and updates reference(s) in its repository.
|
2007-05-12 17:11:13 +00:00
|
|
|
It executes on the remote repository once after all the refs have
|
|
|
|
been updated.
|
|
|
|
|
|
|
|
This hook executes once for the receive operation. It takes no
|
2007-05-12 21:43:11 +00:00
|
|
|
arguments, but gets the same information as the
|
|
|
|
<<pre-receive,'pre-receive'>>
|
2007-05-12 17:11:13 +00:00
|
|
|
hook does on its standard input.
|
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook does not affect the outcome of `git receive-pack`, as it
|
2007-05-12 17:11:13 +00:00
|
|
|
is called after the real work is done.
|
|
|
|
|
2007-08-24 00:44:13 +00:00
|
|
|
This supersedes the <<post-update,'post-update'>> hook in that it gets
|
2007-05-12 21:43:11 +00:00
|
|
|
both old and new values of all the refs in addition to their
|
|
|
|
names.
|
2007-05-12 17:11:13 +00:00
|
|
|
|
2007-05-12 21:43:11 +00:00
|
|
|
Both standard output and standard error output are forwarded to
|
2018-05-03 18:48:24 +00:00
|
|
|
`git send-pack` on the other end, so you can simply `echo` messages
|
2007-05-12 21:43:11 +00:00
|
|
|
for the user.
|
2007-05-12 17:11:13 +00:00
|
|
|
|
|
|
|
The default 'post-receive' hook is empty, but there is
|
|
|
|
a sample script `post-receive-email` provided in the `contrib/hooks`
|
2013-01-21 19:17:53 +00:00
|
|
|
directory in Git distribution, which implements sending commit
|
2007-05-12 17:11:13 +00:00
|
|
|
emails.
|
|
|
|
|
push options: {pre,post}-receive hook learns about push options
The environment variable GIT_PUSH_OPTION_COUNT is set to the number of
push options sent, and GIT_PUSH_OPTION_{0,1,..} is set to the transmitted
option.
The code is not executed as the push options are set to NULL, nor is the
new capability advertised.
There was some discussion back and forth how to present these push options
to the user as there are some ways to do it:
Keep all options in one environment variable
============================================
+ easiest way to implement in Git
- This would make things hard to parse correctly in the hook.
Put the options in files instead,
filenames are in GIT_PUSH_OPTION_FILES
======================================
+ After a discussion about environment variables and shells, we may not
want to put user data into an environment variable (see [1] for example).
+ We could transmit binaries, i.e. we're not bound to C strings as
we are when using environment variables to the user.
+ Maybe easier to parse than constructing environment variable names
GIT_PUSH_OPTION_{0,1,..} yourself
- cleanup of the temporary files is hard to do reliably
- we have race conditions with multiple clients pushing, hence we'd need
to use mkstemp. That's not too bad, but still.
Use environment variables, but restrict to key/value pairs
==========================================================
(When the user pushes a push option `foo=bar`, we'd
GIT_PUSH_OPTION_foo=bar)
+ very easy to parse for a simple model of push options
- it's not sufficient for more elaborate models, e.g.
it doesn't allow doubles (e.g. cc=reviewer@email)
Present the options in different environment variables
======================================================
(This is implemented)
* harder to parse as a user, but we have a sample hook for that.
- doesn't allow binary files
+ allows the same option twice, i.e. is not restrictive about
options, except for binary files.
+ doesn't clutter a remote directory with (possibly stale)
temporary files
As we first want to focus on getting simple strings to work
reliably, we go with the last option for now. If we want to
do transmission of binaries later, we can just attach a
'side-channel', e.g. "any push option that contains a '\0' is
put into a file instead of the environment variable and we'd
have new GIT_PUSH_OPTION_FILES, GIT_PUSH_OPTION_FILENAME_{0,1,..}
environment variables".
[1] 'Shellshock' https://lwn.net/Articles/614218/
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-14 21:49:45 +00:00
|
|
|
The number of push options given on the command line of
|
|
|
|
`git push --push-option=...` can be read from the environment
|
|
|
|
variable `GIT_PUSH_OPTION_COUNT`, and the options themselves are
|
|
|
|
found in `GIT_PUSH_OPTION_0`, `GIT_PUSH_OPTION_1`,...
|
|
|
|
If it is negotiated to not use the push options phase, the
|
|
|
|
environment variables will not be set. If the client selects
|
|
|
|
to use push options, but doesn't transmit any, the count variable
|
|
|
|
will be set to zero, `GIT_PUSH_OPTION_COUNT=0`.
|
|
|
|
|
2007-05-12 17:11:13 +00:00
|
|
|
[[post-update]]
|
2005-09-03 04:19:26 +00:00
|
|
|
post-update
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~~
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
|
|
|
|
`git push` and updates reference(s) in its repository.
|
2006-03-25 03:21:07 +00:00
|
|
|
It executes on the remote repository once after all the refs have
|
|
|
|
been updated.
|
|
|
|
|
|
|
|
It takes a variable number of parameters, each of which is the
|
|
|
|
name of ref that was actually updated.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
|
|
|
This hook is meant primarily for notification, and cannot affect
|
2018-05-03 18:48:24 +00:00
|
|
|
the outcome of `git receive-pack`.
|
2005-09-03 04:19:26 +00:00
|
|
|
|
2006-09-20 10:15:39 +00:00
|
|
|
The 'post-update' hook can tell what are the heads that were pushed,
|
2006-03-25 03:21:07 +00:00
|
|
|
but it does not know what their original and updated values are,
|
2007-05-12 21:43:11 +00:00
|
|
|
so it is a poor place to do log old..new. The
|
|
|
|
<<post-receive,'post-receive'>> hook does get both original and
|
|
|
|
updated values of the refs. You might consider it instead if you need
|
|
|
|
them.
|
2007-05-12 17:11:13 +00:00
|
|
|
|
2006-09-20 10:15:39 +00:00
|
|
|
When enabled, the default 'post-update' hook runs
|
2018-05-03 18:48:24 +00:00
|
|
|
`git update-server-info` to keep the information used by dumb
|
2017-08-23 17:49:35 +00:00
|
|
|
transports (e.g., HTTP) up to date. If you are publishing
|
2013-01-21 19:17:53 +00:00
|
|
|
a Git repository that is accessible via HTTP, you should
|
2006-03-25 03:21:07 +00:00
|
|
|
probably enable this hook.
|
2005-12-20 00:35:48 +00:00
|
|
|
|
2007-05-12 17:11:13 +00:00
|
|
|
Both standard output and standard error output are forwarded to
|
2018-05-03 18:48:24 +00:00
|
|
|
`git send-pack` on the other end, so you can simply `echo` messages
|
2007-05-12 21:43:11 +00:00
|
|
|
for the user.
|
2008-04-02 19:34:55 +00:00
|
|
|
|
2020-07-24 13:57:57 +00:00
|
|
|
reference-transaction
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~
|
refs: implement reference transaction hook
The low-level reference transactions used to update references are
currently completely opaque to the user. While certainly desirable in
most usecases, there are some which might want to hook into the
transaction to observe all queued reference updates as well as observing
the abortion or commit of a prepared transaction.
One such usecase would be to have a set of replicas of a given Git
repository, where we perform Git operations on all of the repositories
at once and expect the outcome to be the same in all of them. While
there exist hooks already for a certain subset of Git commands that
could be used to implement a voting mechanism for this, many others
currently don't have any mechanism for this.
The above scenario is the motivation for the new "reference-transaction"
hook that reaches directly into Git's reference transaction mechanism.
The hook receives as parameter the current state the transaction was
moved to ("prepared", "committed" or "aborted") and gets via its
standard input all queued reference updates. While the exit code gets
ignored in the "committed" and "aborted" states, a non-zero exit code in
the "prepared" state will cause the transaction to be aborted
prematurely.
Given the usecase described above, a voting mechanism can now be
implemented via this hook: as soon as it gets called, it will take all
of stdin and use it to cast a vote to a central service. When all
replicas of the repository agree, the hook will exit with zero,
otherwise it will abort the transaction by returning non-zero. The most
important upside is that this will catch _all_ commands writing
references at once, allowing to implement strong consistency for
reference updates via a single mechanism.
In order to test the impact on the case where we don't have any
"reference-transaction" hook installed in the repository, this commit
introduce two new performance tests for git-update-refs(1). Run against
an empty repository, it produces the following results:
Test origin/master HEAD
--------------------------------------------------------------------
1400.2: update-ref 2.70(2.10+0.71) 2.71(2.10+0.73) +0.4%
1400.3: update-ref --stdin 0.21(0.09+0.11) 0.21(0.07+0.14) +0.0%
The performance test p1400.2 creates, updates and deletes a branch a
thousand times, thus averaging runtime of git-update-refs over 3000
invocations. p1400.3 instead calls `git-update-refs --stdin` three times
and queues a thousand creations, updates and deletes respectively.
As expected, p1400.3 consistently shows no noticeable impact, as for
each batch of updates there's a single call to access(3P) for the
negative hook lookup. On the other hand, for p1400.2, one can see an
impact caused by this patchset. But doing five runs of the performance
tests where each one was run with GIT_PERF_REPEAT_COUNT=10, the overhead
ranged from -1.5% to +1.1%. These inconsistent performance numbers can
be explained by the overhead of spawning 3000 processes. This shows that
the overhead of assembling the hook path and executing access(3P) once
to check if it's there is mostly outweighed by the operating system's
overhead.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-06-19 06:56:14 +00:00
|
|
|
|
|
|
|
This hook is invoked by any Git command that performs reference
|
|
|
|
updates. It executes whenever a reference transaction is prepared,
|
2021-03-01 09:43:55 +00:00
|
|
|
committed or aborted and may thus get called multiple times. The hook
|
|
|
|
does not cover symbolic references (but that may change in the future).
|
refs: implement reference transaction hook
The low-level reference transactions used to update references are
currently completely opaque to the user. While certainly desirable in
most usecases, there are some which might want to hook into the
transaction to observe all queued reference updates as well as observing
the abortion or commit of a prepared transaction.
One such usecase would be to have a set of replicas of a given Git
repository, where we perform Git operations on all of the repositories
at once and expect the outcome to be the same in all of them. While
there exist hooks already for a certain subset of Git commands that
could be used to implement a voting mechanism for this, many others
currently don't have any mechanism for this.
The above scenario is the motivation for the new "reference-transaction"
hook that reaches directly into Git's reference transaction mechanism.
The hook receives as parameter the current state the transaction was
moved to ("prepared", "committed" or "aborted") and gets via its
standard input all queued reference updates. While the exit code gets
ignored in the "committed" and "aborted" states, a non-zero exit code in
the "prepared" state will cause the transaction to be aborted
prematurely.
Given the usecase described above, a voting mechanism can now be
implemented via this hook: as soon as it gets called, it will take all
of stdin and use it to cast a vote to a central service. When all
replicas of the repository agree, the hook will exit with zero,
otherwise it will abort the transaction by returning non-zero. The most
important upside is that this will catch _all_ commands writing
references at once, allowing to implement strong consistency for
reference updates via a single mechanism.
In order to test the impact on the case where we don't have any
"reference-transaction" hook installed in the repository, this commit
introduce two new performance tests for git-update-refs(1). Run against
an empty repository, it produces the following results:
Test origin/master HEAD
--------------------------------------------------------------------
1400.2: update-ref 2.70(2.10+0.71) 2.71(2.10+0.73) +0.4%
1400.3: update-ref --stdin 0.21(0.09+0.11) 0.21(0.07+0.14) +0.0%
The performance test p1400.2 creates, updates and deletes a branch a
thousand times, thus averaging runtime of git-update-refs over 3000
invocations. p1400.3 instead calls `git-update-refs --stdin` three times
and queues a thousand creations, updates and deletes respectively.
As expected, p1400.3 consistently shows no noticeable impact, as for
each batch of updates there's a single call to access(3P) for the
negative hook lookup. On the other hand, for p1400.2, one can see an
impact caused by this patchset. But doing five runs of the performance
tests where each one was run with GIT_PERF_REPEAT_COUNT=10, the overhead
ranged from -1.5% to +1.1%. These inconsistent performance numbers can
be explained by the overhead of spawning 3000 processes. This shows that
the overhead of assembling the hook path and executing access(3P) once
to check if it's there is mostly outweighed by the operating system's
overhead.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-06-19 06:56:14 +00:00
|
|
|
|
|
|
|
The hook takes exactly one argument, which is the current state the
|
|
|
|
given reference transaction is in:
|
|
|
|
|
|
|
|
- "prepared": All reference updates have been queued to the
|
|
|
|
transaction and references were locked on disk.
|
|
|
|
|
|
|
|
- "committed": The reference transaction was committed and all
|
|
|
|
references now have their respective new value.
|
|
|
|
|
|
|
|
- "aborted": The reference transaction was aborted, no changes
|
|
|
|
were performed and the locks have been released.
|
|
|
|
|
|
|
|
For each reference update that was added to the transaction, the hook
|
|
|
|
receives on standard input a line of the format:
|
|
|
|
|
|
|
|
<old-value> SP <new-value> SP <ref-name> LF
|
|
|
|
|
2021-03-01 09:43:55 +00:00
|
|
|
where `<old-value>` is the old object name passed into the reference
|
|
|
|
transaction, `<new-value>` is the new object name to be stored in the
|
|
|
|
ref and `<ref-name>` is the full name of the ref. When force updating
|
|
|
|
the reference regardless of its current value or when the reference is
|
|
|
|
to be created anew, `<old-value>` is the all-zeroes object name. To
|
|
|
|
distinguish these cases, you can inspect the current value of
|
|
|
|
`<ref-name>` via `git rev-parse`.
|
|
|
|
|
refs: implement reference transaction hook
The low-level reference transactions used to update references are
currently completely opaque to the user. While certainly desirable in
most usecases, there are some which might want to hook into the
transaction to observe all queued reference updates as well as observing
the abortion or commit of a prepared transaction.
One such usecase would be to have a set of replicas of a given Git
repository, where we perform Git operations on all of the repositories
at once and expect the outcome to be the same in all of them. While
there exist hooks already for a certain subset of Git commands that
could be used to implement a voting mechanism for this, many others
currently don't have any mechanism for this.
The above scenario is the motivation for the new "reference-transaction"
hook that reaches directly into Git's reference transaction mechanism.
The hook receives as parameter the current state the transaction was
moved to ("prepared", "committed" or "aborted") and gets via its
standard input all queued reference updates. While the exit code gets
ignored in the "committed" and "aborted" states, a non-zero exit code in
the "prepared" state will cause the transaction to be aborted
prematurely.
Given the usecase described above, a voting mechanism can now be
implemented via this hook: as soon as it gets called, it will take all
of stdin and use it to cast a vote to a central service. When all
replicas of the repository agree, the hook will exit with zero,
otherwise it will abort the transaction by returning non-zero. The most
important upside is that this will catch _all_ commands writing
references at once, allowing to implement strong consistency for
reference updates via a single mechanism.
In order to test the impact on the case where we don't have any
"reference-transaction" hook installed in the repository, this commit
introduce two new performance tests for git-update-refs(1). Run against
an empty repository, it produces the following results:
Test origin/master HEAD
--------------------------------------------------------------------
1400.2: update-ref 2.70(2.10+0.71) 2.71(2.10+0.73) +0.4%
1400.3: update-ref --stdin 0.21(0.09+0.11) 0.21(0.07+0.14) +0.0%
The performance test p1400.2 creates, updates and deletes a branch a
thousand times, thus averaging runtime of git-update-refs over 3000
invocations. p1400.3 instead calls `git-update-refs --stdin` three times
and queues a thousand creations, updates and deletes respectively.
As expected, p1400.3 consistently shows no noticeable impact, as for
each batch of updates there's a single call to access(3P) for the
negative hook lookup. On the other hand, for p1400.2, one can see an
impact caused by this patchset. But doing five runs of the performance
tests where each one was run with GIT_PERF_REPEAT_COUNT=10, the overhead
ranged from -1.5% to +1.1%. These inconsistent performance numbers can
be explained by the overhead of spawning 3000 processes. This shows that
the overhead of assembling the hook path and executing access(3P) once
to check if it's there is mostly outweighed by the operating system's
overhead.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-06-19 06:56:14 +00:00
|
|
|
The exit status of the hook is ignored for any state except for the
|
|
|
|
"prepared" state. In the "prepared" state, a non-zero exit status will
|
|
|
|
cause the transaction to be aborted. The hook will not be called with
|
|
|
|
"aborted" state in that case.
|
|
|
|
|
2014-12-01 23:29:54 +00:00
|
|
|
push-to-checkout
|
|
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
|
|
|
|
`git push` and updates reference(s) in its repository, and when
|
2014-12-01 23:29:54 +00:00
|
|
|
the push tries to update the branch that is currently checked out
|
|
|
|
and the `receive.denyCurrentBranch` configuration variable is set to
|
|
|
|
`updateInstead`. Such a push by default is refused if the working
|
|
|
|
tree and the index of the remote repository has any difference from
|
|
|
|
the currently checked out commit; when both the working tree and the
|
|
|
|
index match the current commit, they are updated to match the newly
|
|
|
|
pushed tip of the branch. This hook is to be used to override the
|
|
|
|
default behaviour.
|
|
|
|
|
|
|
|
The hook receives the commit with which the tip of the current
|
|
|
|
branch is going to be updated. It can exit with a non-zero status
|
|
|
|
to refuse the push (when it does so, it must not modify the index or
|
|
|
|
the working tree). Or it can make any necessary changes to the
|
|
|
|
working tree and to the index to bring them to the desired state
|
|
|
|
when the tip of the current branch is updated to the new commit, and
|
|
|
|
exit with a zero status.
|
|
|
|
|
|
|
|
For example, the hook can simply run `git read-tree -u -m HEAD "$1"`
|
2018-05-03 18:48:24 +00:00
|
|
|
in order to emulate `git fetch` that is run in the reverse direction
|
|
|
|
with `git push`, as the two-tree form of `git read-tree -u -m` is
|
2019-03-29 10:39:05 +00:00
|
|
|
essentially the same as `git switch` or `git checkout`
|
|
|
|
that switches branches while
|
2014-12-01 23:29:54 +00:00
|
|
|
keeping the local changes in the working tree that do not interfere
|
|
|
|
with the difference between the branches.
|
|
|
|
|
|
|
|
|
2008-04-02 19:34:55 +00:00
|
|
|
pre-auto-gc
|
2009-09-06 10:22:58 +00:00
|
|
|
~~~~~~~~~~~
|
2008-04-02 19:34:55 +00:00
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by `git gc --auto` (see linkgit:git-gc[1]). It
|
|
|
|
takes no parameter, and exiting with non-zero status from this script
|
|
|
|
causes the `git gc --auto` to abort.
|
2008-05-02 03:30:47 +00:00
|
|
|
|
2010-03-12 17:04:27 +00:00
|
|
|
post-rewrite
|
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked by commands that rewrite commits
|
|
|
|
(linkgit:git-commit[1] when called with `--amend` and
|
Recommend git-filter-repo instead of git-filter-branch
filter-branch suffers from a deluge of disguised dangers that disfigure
history rewrites (i.e. deviate from the deliberate changes). Many of
these problems are unobtrusive and can easily go undiscovered until the
new repository is in use. This can result in problems ranging from an
even messier history than what led folks to filter-branch in the first
place, to data loss or corruption. These issues cannot be backward
compatibly fixed, so add a warning to both filter-branch and its manpage
recommending that another tool (such as filter-repo) be used instead.
Also, update other manpages that referenced filter-branch. Several of
these needed updates even if we could continue recommending
filter-branch, either due to implying that something was unique to
filter-branch when it applied more generally to all history rewriting
tools (e.g. BFG, reposurgeon, fast-import, filter-repo), or because
something about filter-branch was used as an example despite other more
commonly known examples now existing. Reword these sections to fix
these issues and to avoid recommending filter-branch.
Finally, remove the section explaining BFG Repo Cleaner as an
alternative to filter-branch. I feel somewhat bad about this,
especially since I feel like I learned so much from BFG that I put to
good use in filter-repo (which is much more than I can say for
filter-branch), but keeping that section presented a few problems:
* In order to recommend that people quit using filter-branch, we need
to provide them a recomendation for something else to use that
can handle all the same types of rewrites. To my knowledge,
filter-repo is the only such tool. So it needs to be mentioned.
* I don't want to give conflicting recommendations to users
* If we recommend two tools, we shouldn't expect users to learn both
and pick which one to use; we should explain which problems one
can solve that the other can't or when one is much faster than
the other.
* BFG and filter-repo have similar performance
* All filtering types that BFG can do, filter-repo can also do. In
fact, filter-repo comes with a reimplementation of BFG named
bfg-ish which provides the same user-interface as BFG but with
several bugfixes and new features that are hard to implement in
BFG due to its technical underpinnings.
While I could still mention both tools, it seems like I would need to
provide some kind of comparison and I would ultimately just say that
filter-repo can do everything BFG can, so ultimately it seems that it
is just better to remove that section altogether.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-09-04 22:32:38 +00:00
|
|
|
linkgit:git-rebase[1]; however, full-history (re)writing tools like
|
|
|
|
linkgit:git-fast-import[1] or
|
|
|
|
https://github.com/newren/git-filter-repo[git-filter-repo] typically
|
|
|
|
do not call it!). Its first argument denotes the command it was
|
|
|
|
invoked by: currently one of `amend` or `rebase`. Further
|
|
|
|
command-dependent arguments may be passed in the future.
|
2010-03-12 17:04:27 +00:00
|
|
|
|
|
|
|
The hook receives a list of the rewritten commits on stdin, in the
|
|
|
|
format
|
|
|
|
|
2021-03-01 09:43:47 +00:00
|
|
|
<old-object-name> SP <new-object-name> [ SP <extra-info> ] LF
|
2010-03-12 17:04:27 +00:00
|
|
|
|
|
|
|
The 'extra-info' is again command-dependent. If it is empty, the
|
|
|
|
preceding SP is also omitted. Currently, no commands pass any
|
|
|
|
'extra-info'.
|
|
|
|
|
2010-03-12 17:04:32 +00:00
|
|
|
The hook always runs after the automatic note copying (see
|
2016-03-21 18:38:34 +00:00
|
|
|
"notes.rewrite.<command>" in linkgit:git-config[1]) has happened, and
|
2010-03-12 17:04:32 +00:00
|
|
|
thus has access to these notes.
|
|
|
|
|
2010-03-12 17:04:27 +00:00
|
|
|
The following command-specific comments apply:
|
|
|
|
|
|
|
|
rebase::
|
|
|
|
For the 'squash' and 'fixup' operation, all commits that were
|
|
|
|
squashed are listed as being rewritten to the squashed commit.
|
|
|
|
This means that there will be several lines sharing the same
|
2021-03-01 09:43:47 +00:00
|
|
|
'new-object-name'.
|
2010-03-12 17:04:27 +00:00
|
|
|
+
|
|
|
|
The commits are guaranteed to be listed in the order that they were
|
|
|
|
processed by rebase.
|
|
|
|
|
2017-05-12 22:38:26 +00:00
|
|
|
sendemail-validate
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2023-04-19 20:27:03 +00:00
|
|
|
This hook is invoked by linkgit:git-send-email[1].
|
|
|
|
|
|
|
|
It takes these command line arguments. They are,
|
|
|
|
1. the name of the file which holds the contents of the email to be sent.
|
|
|
|
2. The name of the file which holds the SMTP headers of the email.
|
|
|
|
|
|
|
|
The SMTP headers are passed in the exact same way as they are passed to the
|
|
|
|
user's Mail Transport Agent (MTA). In effect, the email given to the user's
|
|
|
|
MTA, is the contents of $2 followed by the contents of $1.
|
|
|
|
|
|
|
|
An example of a few common headers is shown below. Take notice of the
|
|
|
|
capitalization and multi-line tab structure.
|
|
|
|
|
|
|
|
From: Example <from@example.com>
|
|
|
|
To: to@example.com
|
|
|
|
Cc: cc@example.com,
|
|
|
|
A <author@example.com>,
|
|
|
|
One <one@example.com>,
|
|
|
|
two@example.com
|
|
|
|
Subject: PATCH-STRING
|
|
|
|
|
|
|
|
Exiting with a non-zero status causes `git send-email` to abort
|
|
|
|
before sending any e-mails.
|
2017-05-12 22:38:26 +00:00
|
|
|
|
2023-04-14 15:52:49 +00:00
|
|
|
The following environment variables are set when executing the hook.
|
|
|
|
|
|
|
|
`GIT_SENDEMAIL_FILE_COUNTER`::
|
|
|
|
A 1-based counter incremented by one for every file holding an e-mail
|
|
|
|
to be sent (excluding any FIFOs). This counter does not follow the
|
|
|
|
patch series counter scheme. It will always start at 1 and will end at
|
|
|
|
GIT_SENDEMAIL_FILE_TOTAL.
|
|
|
|
|
|
|
|
`GIT_SENDEMAIL_FILE_TOTAL`::
|
|
|
|
The total number of files that will be sent (excluding any FIFOs). This
|
|
|
|
counter does not follow the patch series counter scheme. It will always
|
|
|
|
be equal to the number of files being sent, whether there is a cover
|
|
|
|
letter or not.
|
|
|
|
|
|
|
|
These variables may for instance be used to validate patch series.
|
|
|
|
|
|
|
|
The sample `sendemail-validate` hook that comes with Git checks that all sent
|
|
|
|
patches (excluding the cover letter) can be applied on top of the upstream
|
|
|
|
repository default branch without conflicts. Some placeholders are left for
|
|
|
|
additional validation steps to be performed after all patches of a given series
|
|
|
|
have been applied.
|
|
|
|
|
2017-09-22 16:35:41 +00:00
|
|
|
fsmonitor-watchman
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2018-05-03 18:48:24 +00:00
|
|
|
This hook is invoked when the configuration option `core.fsmonitor` is
|
2020-01-23 15:26:47 +00:00
|
|
|
set to `.git/hooks/fsmonitor-watchman` or `.git/hooks/fsmonitor-watchmanv2`
|
|
|
|
depending on the version of the hook to use.
|
|
|
|
|
|
|
|
Version 1 takes two arguments, a version (1) and the time in elapsed
|
|
|
|
nanoseconds since midnight, January 1, 1970.
|
|
|
|
|
|
|
|
Version 2 takes two arguments, a version (2) and a token that is used
|
|
|
|
for identifying changes since the token. For watchman this would be
|
|
|
|
a clock id. This version must output to stdout the new token followed
|
|
|
|
by a NUL before the list of files.
|
2017-09-22 16:35:41 +00:00
|
|
|
|
|
|
|
The hook should output to stdout the list of all files in the working
|
|
|
|
directory that may have changed since the requested time. The logic
|
|
|
|
should be inclusive so that it does not miss any potential changes.
|
|
|
|
The paths should be relative to the root of the working directory
|
|
|
|
and be separated by a single NUL.
|
|
|
|
|
|
|
|
It is OK to include files which have not actually changed. All changes
|
|
|
|
including newly-created and deleted files should be included. When
|
|
|
|
files are renamed, both the old and the new name should be included.
|
|
|
|
|
|
|
|
Git will limit what files it checks for changes as well as which
|
|
|
|
directories are checked for untracked files based on the path names
|
|
|
|
given.
|
|
|
|
|
|
|
|
An optimized way to tell git "all files have changed" is to return
|
2018-05-03 18:48:24 +00:00
|
|
|
the filename `/`.
|
2017-09-22 16:35:41 +00:00
|
|
|
|
|
|
|
The exit status determines whether git will use the data from the
|
|
|
|
hook to limit its search. On error, it will fall back to verifying
|
|
|
|
all files and folders.
|
2010-03-12 17:04:27 +00:00
|
|
|
|
2020-02-14 14:44:45 +00:00
|
|
|
p4-changelist
|
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
This hook is invoked by `git-p4 submit`.
|
|
|
|
|
|
|
|
The `p4-changelist` hook is executed after the changelist
|
|
|
|
message has been edited by the user. It can be bypassed with the
|
|
|
|
`--no-verify` option. It takes a single parameter, the name
|
|
|
|
of the file that holds the proposed changelist text. Exiting
|
|
|
|
with a non-zero status causes the command to abort.
|
|
|
|
|
|
|
|
The hook is allowed to edit the changelist file and can be used
|
|
|
|
to normalize the text into some project standard format. It can
|
|
|
|
also be used to refuse the Submit after inspect the message file.
|
|
|
|
|
|
|
|
Run `git-p4 submit --help` for details.
|
|
|
|
|
|
|
|
p4-prepare-changelist
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
This hook is invoked by `git-p4 submit`.
|
|
|
|
|
|
|
|
The `p4-prepare-changelist` hook is executed right after preparing
|
|
|
|
the default changelist message and before the editor is started.
|
|
|
|
It takes one parameter, the name of the file that contains the
|
|
|
|
changelist text. Exiting with a non-zero status from the script
|
|
|
|
will abort the process.
|
|
|
|
|
|
|
|
The purpose of the hook is to edit the message file in place,
|
2021-01-03 14:25:50 +00:00
|
|
|
and it is not suppressed by the `--no-verify` option. This hook
|
2020-02-14 14:44:45 +00:00
|
|
|
is called even if `--prepare-p4-only` is set.
|
|
|
|
|
|
|
|
Run `git-p4 submit --help` for details.
|
|
|
|
|
|
|
|
p4-post-changelist
|
|
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
This hook is invoked by `git-p4 submit`.
|
|
|
|
|
|
|
|
The `p4-post-changelist` hook is invoked after the submit has
|
2020-11-05 20:48:14 +00:00
|
|
|
successfully occurred in P4. It takes no parameters and is meant
|
2020-02-14 14:44:45 +00:00
|
|
|
primarily for notification and cannot affect the outcome of the
|
|
|
|
git p4 submit action.
|
|
|
|
|
|
|
|
Run `git-p4 submit --help` for details.
|
|
|
|
|
2018-07-27 11:22:22 +00:00
|
|
|
p4-pre-submit
|
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
This hook is invoked by `git-p4 submit`. It takes no parameters and nothing
|
|
|
|
from standard input. Exiting with non-zero status from this script prevent
|
2020-02-11 18:58:01 +00:00
|
|
|
`git-p4 submit` from launching. It can be bypassed with the `--no-verify`
|
|
|
|
command line option. Run `git-p4 submit --help` for details.
|
|
|
|
|
|
|
|
|
2018-07-27 11:22:22 +00:00
|
|
|
|
2019-02-15 17:59:21 +00:00
|
|
|
post-index-change
|
|
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
This hook is invoked when the index is written in read-cache.c
|
|
|
|
do_write_locked_index.
|
|
|
|
|
|
|
|
The first parameter passed to the hook is the indicator for the
|
|
|
|
working directory being updated. "1" meaning working directory
|
|
|
|
was updated or "0" when the working directory was not updated.
|
|
|
|
|
|
|
|
The second parameter passed to the hook is the indicator for whether
|
|
|
|
or not the index was updated and the skip-worktree bit could have
|
|
|
|
changed. "1" meaning skip-worktree bits could have been updated
|
|
|
|
and "0" meaning they were not.
|
|
|
|
|
|
|
|
Only one parameter should be set to "1" when the hook runs. The hook
|
|
|
|
running passing "1", "1" should not be possible.
|
|
|
|
|
2021-12-22 03:59:27 +00:00
|
|
|
SEE ALSO
|
|
|
|
--------
|
|
|
|
linkgit:git-hook[1]
|
|
|
|
|
2008-05-02 03:30:47 +00:00
|
|
|
GIT
|
|
|
|
---
|
2008-06-06 07:07:32 +00:00
|
|
|
Part of the linkgit:git[1] suite
|