## 命名

githooks - Git 使用的挂钩

## 概要

$GIT_DIR/hooks/* (or `git config core.hooksPath`/*)

## 描述

Hook 是你可以放在钩子目录中的程序，以触发 git 执行中某些点的动作。没有可执行位设置的 Hook 将被忽略。

默认情况下，Hook 目录是`$GIT_DIR/hooks`，但可以通过`core.hooksPath`配置变量来更改（参见 git-config [1]）。

在 Git 调用 hook 之前，它将其工作目录更改为裸仓库中的 $ GIT_DIR 或非裸仓库中工作树的根。一个例外是推（内触发挂钩`pre-receive`，`update`，`post-receive`，`post-update`，`push-to-checkout`它们总是在 $ GIT_DIR 执行）。

Hook 可以通过环境，命令行参数和 stdin 获得它们的参数。有关详细信息，请参阅下面每个挂钩的文档。

`git init` 可能会将钩子复制到新的存储库，具体取决于其配置。有关详细信息，请参阅 git-init [1] 中的 “TEMPLATE DIRECTORY” 部分。当本文档的其余部分提到“default hooks”时，它将讨论 Git 附带的默认模板。

下面介绍当前支持的 hook 。

## Hooks

### applypatch-msg

这个 hook 被调用`git am`。它采用一个参数，即包含提议的提交日志消息的文件的名称。以非零状态退出导致`git am`在应用修补程序之前中止。

允许 hook 编辑消息文件，并可用于将消息标准化为某种项目标准格式。在检查消息文件之后，它也可以用来拒绝提交。

默认`applypatch-msg`挂钩在启用时运行`commit-msg` hook（如果后者已启用）。

### pre-applypatch

这个 hook 被调用`git am`。它不接受任何参数，并在应用修补程序后调用，但在提交之前调用。

如果它以非零状态退出，则在应用修补程序后，工作树不会被提交。

它可以用来检查当前的工作树，如果它没有通过某些测试，就拒绝提交。

默认`pre-applypatch` hook 在启用时运行`pre-commit` hook（如果后者已启用）。

### post-applypatch

这个 hook 被调用`git am`。它不接受任何参数，并在应用修补程序并进行提交后调用。

这个 hook 主要是为了通知，并不能影响结果`git am`。

### pre-commit

该 hook 由`git commit`该`--no-verify`选项调用，并且可以绕过该选项。它不接受任何参数，并在获取建议的提交日志消息并进行提交之前调用它。从该脚本中退出非零状态会导致该`git commit`命令在创建提交之前中止。

默认`pre-commit` hook 启用后，会捕获带有尾随空白的行的介绍，并在找到这样的行时中止提交。

如果该命令不会`git commit`调用`GIT_EDITOR=:`编辑器来修改提交消息，则所有钩子都将使用环境变量进行调用。

### prepare-commit-msg

`git commit`在编写默认日志消息之后，在编辑器启动之前，该 hook 被调用。

它需要一到三个参数。第一个是包含提交日志消息的文件的名称。第二个是提交消息的来源，可以是：（`message`如果给出了a `-m`或`-F`选项）; `template`（如果`-t`给出选项或`commit.template`设置了配置选项）; `merge`（如果提交是合并或`.git/MERGE_MSG`文件存在）; `squash`（如果`.git/SQUASH_MSG`存在文件）; 或者`commit`，后跟提交 SHA-1（如果是`-c`，`-C`或`--amend`给予选项）。

如果退出状态不为零，`git commit`则会中止。

Hook 的目的是编辑邮件文件，并且不会被该`--no-verify`选项抑制。非零的退出意味着挂钩失败并放弃提交。它不应该被用作预提交 hook 的替换。

`prepare-commit-msg` Git 附带的示例钩子会注释`Conflicts:`合并的提交消息的一部分。

### commit-msg

该 hook 由`git commit`选项调用，并且可以绕过`--no-verify`选项。它采用一个参数，即包含提议的提交日志消息的文件的名称。以非零状态退出会导致`git commit`中止。

允许 hook 编辑消息文件，并可用于将消息标准化为某种项目标准格式。在检查消息文件之后，它也可以用来拒绝提交。

默认`commit-msg` hook 启用时检测到重复的 “Signed-off-by” 行，如果找到，则终止提交。

### post-commit

这个 hook 被`git commit`调用。它不接受任何参数，并在提交完成后调用。

这个 hook 主要是为了通知，并不能影响`git commit的`结果。

### pre-rebase

此 hook 被调用`git rebase`并且可以用来防止分支得到重建。挂钩可以用一个或两个参数调用。第一个参数是系列分叉的上游。第二个参数是重新分支的分支，并在重新绑定当前分支时未设置。

### post-checkout

当`git checkout`更新工作树后运行a时会调用此钩子。这个钩子有三个参数：前一个 HEAD 的 ref ，新 HEAD 的 ref（可能或者可能没有改变）以及一个标志，指示结帐是否是分支结账（改变分支，标志= 1）或者一个文件签出（从索引中检索一个文件，flag = 0）。这个钩子不能影响结果`git checkout`。

它也在之后运行`git clone`，除非使用 --no-checkout（-n）选项。给 hook 的第一个参数是 null-ref ，是新 HEAD 的 ref 的第二个参数，并且该标志始终为1。

该 hook 可用于执行存储库有效性检查，自动显示与以前 HEAD 不同的区别，或设置工作目录元数据属性。

### post-merge

这个 hook 被调用`git merge`，当`git pull`在本地仓库上完成时发生。挂钩采用一个参数，一个状态标志指定是否合并完成是一个壁球合并。`git merge`如果合并因冲突而失败，则此挂接不会影响结果并且不会执行。

该 hook 可以与相应的预提交钩子结合使用，以保存和恢复任何形式的与工作树关联的元数据（例如：权限/所有权，ACLS 等）。有关如何执行此操作的示例，请参阅 contrib / hooks / setgitperms.perl 。

### pre-push

这个 hook 被调用`git push`，可以用来防止发生推送。该钩子被调用时提供了两个参数，它们提供目标远程的名称和位置，如果没有使用一个命名的远程，那么这两个值都是相同的。

有关要推送什么的信息通过以下格式的线条在 hook 的标准输入上提供：

    <local ref> SP <local sha1> SP <remote ref> SP <remote sha1> LF

例如，如果`git push origin master:foreign`运行该命令， hook 将收到如下所示的行：

    refs/heads/master 67890 refs/heads/foreign 12345

尽管将提供完整的40个字符的 SHA-1 。如果国外裁判不存在，`<remote SHA-1>`将是40 `0`。如果一个裁判将被删除，`<local ref>`将提供作为`(delete)`和`<local SHA-1>`将是40 `0`。如果本地提交是由可扩展的名称以外的其他名称指定的（例如`HEAD~`，或 SHA-1 ），则它将按原来的形式提供。

如果此 hook 以非零状态退出，`git push`将不中断任何操作而中止。有关推送被拒绝的原因可通过写入标准错误发送给用户。

### pre-receive

这个 hook 是`git-receive-pack`在远程仓库上调用的，当`git push`在本地仓库上完成时会发生这种情况。在开始更新远程仓库中的 refs 之前，调用预接收 hook 。其退出状态决定了更新的成败。

该 hook 为接收操作执行一次。它不需要任何参数，但是对于每个要更新的引用，它都会在标准输入中接收格式的一行：

    <old-value> SP <new-value> SP <ref-name> LF

在`<old-value>` ref 中存储的旧对象名称是在 ref 中存储`<new-value>`的新对象名称，并且`<ref-name>`是 ref 的全名。当创建一个新的参考，`<old-value>`是40 `0`。

如果 hook 以非零状态退出，则没有任何参数会被更新。如果钩子具有零退出，从个人参更新仍可以通过防止更新钩。

标准输出和标准错误输出都被转发到`git send-pack`另一端，因此您可以简单地`echo`向用户发送消息。

命令行定推送选项的数量`git push --push-option=...`可以从环境变量中读取`GIT_PUSH_OPTION_COUNT`本身中找到的选项，并且`GIT_PUSH_OPTION_0`，`GIT_PUSH_OPTION_1`......如果协商不使用推送选项阶段，环境变量将不会被设置。如果客户选择使用推送选项，但不传送任何数据，则计数变量将被设置为零`GIT_PUSH_OPTION_COUNT=0`。

有关注意事项，请参阅 git-receive-pack [1] 中的“隔离环境”部分。

### update

这个 hook 是`git-receive-pack`在远程仓库上调用的，当`git push`在本地仓库上完成时会发生这种情况。在更新远程存储库中的 ref 之前，会调用更新挂钩。它的退出状态决定了 ref 更新的成败。

该 hook 为每个要更新的引用执行一次，并且需要三个参数：

- 正在更新的参考名称，

- 旧的对象名称存储在 ref 中，

- 并将新的对象名称存储在 ref 中。

从更新挂钩零退出允许 ref 被更新。以非零状态退出可防止`git-receive-pack`更新该引用。

`forced`通过确保对象名称是一个提交对象，该对象是旧对象名称所指定的提交对象的后代，该 hook 可用于防止更新某些引用。也就是说，强制执行“仅快进”策略。

它也可以用来记录旧的......新状态。但是，它并不知道整套分支，所以最终会在天真地使用时为每个参考文献发送一封电子邮件。在后收到钩更适合一点。

在一个限制用户仅通过线路访问 git 命令的环境中，该 hook 可用于实现访问控制，而不依赖文件系统所有权和组成员身份。有关如何使用登录 shell 来限制用户对 git 命令的访问，请参阅 git-shell [1]。

标准输出和标准错误输出都被转发到`git send-pack`另一端，因此您可以简单地`echo`向用户发送消息。

默认`update` hook `hooks.allowunannotated`启用时（且配置选项未设置或设置为false）可防止未注释的标签被推送。

### post-receive

这个 hook 是`git-receive-pack`在远程仓库上调用的，当`git push`在本地仓库上完成时会发生这种情况。它在更新所有 ref 后立即在远程存储库上执行。

该 hook 为接收操作执行一次。它不需要任何参数，但会获得与预接收钩子在其标准输入上相同的信息。

这个 hook 并不影响结果`git-receive-pack`，因为它是在真正的工作完成后调用的。

这取代了更新后的 hook ，它除了获得所有参考名称之外，还获得了所有参考的新旧值。

标准输出和标准错误输出都被转发到`git send-pack`另一端，因此您可以简单地`echo`向用户发送消息。

默认`post-receive` hook 为空，但在 Git 分配`post-receive-email`的`contrib/hooks`目录中提供了一个示例脚本，该脚本实现了发送提交邮件。

命令行定推送选项的数量`git push --push-option=...`可以从环境变量中读取`GIT_PUSH_OPTION_COUNT`本身中找到的选项，并且`GIT_PUSH_OPTION_0`，`GIT_PUSH_OPTION_1`......如果协商不使用推送选项阶段，环境变量将不会被设置。如果客户选择使用推送选项，但不传送任何数据，则计数变量将被设置为零`GIT_PUSH_OPTION_COUNT=0`。

### post-update

这个 hook 是`git-receive-pack`在远程仓库上调用的，当`git push`在本地仓库上完成时会发生这种情况。它在更新所有 ref 后立即在远程存储库上执行。

它需要可变数量的参数，每个参数都是实际更新的 ref 的名称。

这个 hook 主要是为了通知，并不能影响结果`git-receive-pack`。

该`post-update`能告诉什么是推送的头，但它不知道他们原来的和更新的值，所以它是做记录 old..new 一个穷地方。在后收到 hook 并得到裁判的原件和更新的值。如果你需要它们，你可以考虑它。

启用后，默认`post-update`将运行`git update-server-info`以保持传输（例如，HTTP）使用的信息最新。如果您正在发布可通过HTTP访问的Git存储库，则应该启用此挂接。

标准输出和标准错误输出都被转发到`git send-pack`另一端，因此您可以简单地`echo`向用户发送消息。

### push-to-checkout

该钩子由`git-receive-pack`远程存储库调用`git push`，当在本地存储库上完成a操作时，当推送尝试更新当前检出的分支并将`receive.denyCurrentBranch`配置变量设置为`updateInstead`。如果远程存储库的工作树和索引与当前检出的提交有任何不同，则默认情况下会拒绝这种推送; 当工作树和索引都与当前提交匹配时，它们会更新以匹配分支的新推入的提示。该钩子将用于覆盖默认行为。

钩子接收当前分支的尖端将被更新的提交。它可以以非零状态退出以拒绝推送（当它这样做时，它不能修改索引或工作树）。或者，它可以对工作树和索引进行任何必要的更改，以在当前分支的提示更新为新提交时将其带到期望的状态，并以零状态退出。

例如，钩子可以简单地运行`git read-tree -u -m HEAD "$1"`，以模拟`git fetch`与反向运行的钩子`git push`，因为双树形式`read-tree -u -m`基本上与`git checkout`开关分支相同，同时保持工作树中不会干扰的局部变化分支之间的差异。

### pre-auto-gc

这个钩子被调用`git gc --auto`。它不接受任何参数，并从此脚本中`git gc --auto`以非零状态退出导致中止。

### post-rewrite

这个钩子被重写提交的命令调用（`git commit --amend`，`git-rebase`;目前`git-filter-branch`确实`not`叫它！）。它的第一个参数表示它被调用的命令：当前是`amend`or的一个`rebase`。更多的依赖于命令的参数可能会在未来传递。

该钩子以格式接收stdin上重写的提交列表

    <old-sha1> SP <new-sha1> [ SP <extra-info> ] LF

这又`extra-info`是依赖于命令的。如果它是空的，则前面的SP也被省略。目前，没有命令通过任何`extra-info`。

钩子总是在自动音符复制之后运行（请参阅git-config [1]中的“notes.rewrite。<command>”），因此可以访问这些音符。

以下特定于命令的注释适用于：

rebase

对于`squash`和`fixup`操作，被压扁，所有提交被列为被改写成压扁的承诺。这意味着将会有几条线路共享相同的信息`new-sha1`。

提交将保证按照他们通过rebase处理的顺序列出。

### sendemail-validate

这个钩子被调用`git send-email`。它需要一个参数，即保存要发送的电子邮件的文件的名称。以非零状态退出导致`git send-email`在发送任何电子邮件之前中止。