简体中文 ▾ 主题 ▾ 最新版本 ▾ githooks 上次更新于 2.46.1

名称

githooks - Git 使用的钩子

概要

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

描述

钩子是可以放置在钩子目录中的程序,用于在 Git 执行的特定点触发操作。未设置可执行位的钩子将被忽略。

默认情况下,钩子目录是 $GIT_DIR/hooks,但可以通过 core.hooksPath 配置变量进行更改 (请参阅 git-config[1])。

在 Git 调用钩子之前,它会将其工作目录更改为裸仓库中的 $GIT_DIR 或非裸仓库中工作树的根目录。一个例外是在推送期间触发的钩子 (pre-receiveupdatepost-receivepost-updatepush-to-checkout),它们始终在 $GIT_DIR 中执行。

诸如 GIT_DIRGIT_WORK_TREE 等环境变量会被导出,以便钩子运行的 Git 命令可以正确找到仓库。如果您的钩子需要在外部仓库或同一仓库的不同工作树中调用 Git 命令,则应清除这些环境变量,以使其不会干扰外部位置的 Git 操作。 例如

local_desc=$(git describe)
foreign_desc=$(unset $(git rev-parse --local-env-vars); git -C ../foreign-repo describe)

钩子可以通过环境变量、命令行参数和 stdin 获取其参数。 有关详细信息,请参见以下每个钩子的文档。

根据其配置,git init 可能会将钩子复制到新仓库。 有关详细信息,请参见 git-init[1] 中的“模板目录”部分。 当本文档的其余部分提及“默认钩子”时,它指的是 Git 附带的默认模板。

下面描述了当前支持的钩子。

钩子

applypatch-msg

此钩子由 git-am[1] 调用。它接受一个参数,即保存建议的提交日志消息的文件名。 以非零状态退出会导致 git am 在应用补丁之前中止。

该钩子允许就地编辑消息文件,并可用于将消息规范化为某些项目标准格式。它也可以用于在检查消息文件后拒绝提交。

默认情况下,如果启用了 applypatch-msg 钩子,则将运行 commit-msg 钩子(如果已启用)。

pre-applypatch

此钩子由 git-am[1] 调用。 它不接受参数,并在应用补丁之后但在进行提交之前调用。

如果它以非零状态退出,则在应用补丁后,将不会提交工作树。

它可用于检查当前工作树,如果未通过某些测试,则拒绝进行提交。

默认情况下,如果启用了 pre-applypatch 钩子,则将运行 pre-commit 钩子(如果已启用)。

post-applypatch

此钩子由 git-am[1] 调用。 它不接受参数,并在应用补丁并进行提交之后调用。

此钩子主要用于通知,并且不会影响 git am 的结果。

pre-commit

此钩子由 git-commit[1] 调用,并且可以使用 --no-verify 选项绕过。它不接受参数,并在获取建议的提交日志消息并进行提交之前调用。 如果此脚本以非零状态退出,则 git commit 命令将在创建提交之前中止。

默认情况下,如果启用了 pre-commit 钩子,它将捕获引入的带有尾随空格的行,并在找到此类行时中止提交。

如果命令不会启动编辑器来修改提交消息,则所有 git commit 钩子都会使用环境变量 GIT_EDITOR=: 调用。

默认情况下,如果启用了 pre-commit 钩子,并且未设置或设置为 false 的 hooks.allownonascii 配置选项,则可以防止使用非 ASCII 文件名。

pre-merge-commit

此钩子由 git-merge[1] 调用,并且可以使用 --no-verify 选项绕过。它不接受参数,并在成功执行合并之后以及获取建议的提交日志消息以进行提交之前调用。 如果此脚本以非零状态退出,则 git merge 命令将在创建提交之前中止。

默认情况下,如果启用了 pre-merge-commit 钩子,则将运行 pre-commit 钩子(如果已启用)。

如果命令不会启动编辑器来修改提交消息,则会使用环境变量 GIT_EDITOR=: 调用此钩子。

如果无法自动执行合并,则需要解决冲突并单独提交结果(请参阅 git-merge[1])。 此时,将不会执行此钩子,但是如果启用了 pre-commit 钩子,则将执行此钩子。

prepare-commit-msg

此钩子由 git-commit[1] 在准备默认日志消息之后且编辑器启动之前立即调用。

它接受一到三个参数。 第一个参数是包含提交日志消息的文件名。 第二个是提交消息的来源,可以是:message (如果给定了 -m-F 选项);template (如果给定了 -t 选项或设置了配置选项 commit.template);merge (如果提交是合并或存在 .git/MERGE_MSG 文件);squash (如果存在 .git/SQUASH_MSG 文件);或 commit,后跟提交对象名称(如果给定了 -c-C--amend 选项)。

如果退出状态为非零,则 git commit 将中止。

此钩子的目的是就地编辑消息文件,并且不会被 --no-verify 选项禁止。 非零退出表示钩子失败并中止提交。 它不应替代 pre-commit 钩子。

Git 随附的示例 prepare-commit-msg 钩子会删除提交模板注释部分中的帮助消息。

commit-msg

此钩子由 git-commit[1]git-merge[1] 调用,并且可以使用 --no-verify 选项绕过。它接受一个参数,即保存建议的提交日志消息的文件名。 以非零状态退出会导致命令中止。

该钩子允许就地编辑消息文件,并可用于将消息规范化为某些项目标准格式。它也可以用于在检查消息文件后拒绝提交。

默认情况下,如果启用了 commit-msg 钩子,它将检测重复的 Signed-off-by 尾部,如果找到一个,则中止提交。

post-commit

此钩子由 git-commit[1] 调用。 它不接受参数,并在进行提交之后调用。

此钩子主要用于通知,并且不会影响 git commit 的结果。

pre-rebase

此钩子由 git-rebase[1] 调用,可用于防止分支被 rebase。可以使用一个或两个参数调用该钩子。 第一个参数是从中派生序列的上游。 第二个参数是要 rebase 的分支,在 rebase 当前分支时未设置。

post-checkout

git-checkout[1]git-switch[1] 在更新工作区后运行时,将调用此钩子。该钩子接受三个参数:前一个 HEAD 的引用、新 HEAD 的引用(可能已更改,也可能未更改)以及一个标志,指示检出是分支检出(更改分支,flag=1)还是文件检出(从索引中检索文件,flag=0)。除了钩子的退出状态变为这两个命令的退出状态之外,此钩子不能影响 git switchgit checkout 的结果。

它也在 git-clone[1] 之后运行,除非使用了 --no-checkout (-n) 选项。传递给钩子的第一个参数是 null-ref,第二个参数是新 HEAD 的引用,并且标志始终为 1。对于 git worktree add 也是如此,除非使用了 --no-checkout

此钩子可用于执行存储库有效性检查、自动显示与前一个 HEAD 的差异(如果不同),或设置工作目录元数据属性。

post-merge

此钩子由 git-merge[1] 调用,当在本地存储库上完成 git pull 时会发生这种情况。该钩子接受一个参数,即一个状态标志,指定正在完成的合并是否为 squash 合并。此钩子不能影响 git merge 的结果,并且如果由于冲突导致合并失败,则不会执行。

此钩子可以与相应的 pre-commit 钩子结合使用,以保存和恢复与工作树关联的任何形式的元数据(例如:权限/所有权、ACL 等)。有关如何执行此操作的示例,请参阅 contrib/hooks/setgitperms.perl。

pre-push

此钩子由 git-push[1] 调用,可用于阻止推送的发生。该钩子使用两个参数调用,这两个参数提供目标远程端的名称和位置,如果未使用命名远程端,则这两个值将相同。

有关要推送的内容的信息以以下形式的行提供在钩子的标准输入上

<local-ref> SP <local-object-name> SP <remote-ref> SP <remote-object-name> LF

例如,如果运行命令 git push origin master:foreign,则钩子将收到如下所示的行

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

虽然将提供完整的对象名称。如果 foreign 引用尚不存在,则 <remote-object-name> 将是全零对象名称。如果要删除引用,则 <local-ref> 将作为 (delete) 提供,而 <local-object-name> 将是全零对象名称。如果本地提交是由其他无法展开的名称(例如 HEAD~ 或对象名称)指定的,则将按原始方式提供。

如果此钩子以非零状态退出,则 git push 将中止而不推送任何内容。有关推送被拒绝的原因的信息可以通过写入标准错误来发送给用户。

pre-receive

git-receive-pack[1]git push 做出反应并在其存储库中更新引用时,会调用此钩子。在开始更新远程存储库上的引用之前,将调用 pre-receive 钩子。它的退出状态决定了更新的成功或失败。

此钩子为接收操作执行一次。它不带任何参数,但对于要更新的每个引用,它会在标准输入上接收以下格式的一行

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

其中 <old-oid> 是存储在引用中的旧对象名称,<new-oid> 是要存储在引用中的新对象名称,而 <ref-name> 是引用的完整名称。创建新引用时,<old-oid> 是全零对象名称。

如果钩子以非零状态退出,则不会更新任何引用。如果钩子以零退出,则仍然可以通过 update 钩子阻止对各个引用的更新。

标准输出和标准错误输出都会转发到另一端的 git send-pack,因此您可以简单地 echo 消息给用户。

可以使用环境变量 GIT_PUSH_OPTION_COUNT 读取 git push --push-option=... 命令行上给定的推送选项的数量,这些选项本身可以在 GIT_PUSH_OPTION_0, GIT_PUSH_OPTION_1,… 中找到。如果协商不使用推送选项阶段,则不会设置环境变量。如果客户端选择使用推送选项,但未传输任何选项,则计数变量将设置为零,GIT_PUSH_OPTION_COUNT=0

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

update

git-receive-pack[1]git push 做出反应并在其存储库中更新引用时,会调用此钩子。在更新远程存储库上的引用之前,将调用 update 钩子。它的退出状态决定了引用更新的成功或失败。

该钩子为要更新的每个引用执行一次,并接受三个参数

  • 正在更新的引用的名称,

  • 存储在引用中的旧对象名称,

  • 以及要存储在引用中的新对象名称。

从 update 钩子退出时返回零允许更新引用。以非零状态退出会阻止 git receive-pack 更新该引用。

此钩子可用于通过确保对象名称是提交对象,该提交对象是由旧对象名称命名的提交对象的后代,来防止对某些引用进行强制更新。也就是说,强制执行“仅快进”策略。

它也可以用于记录 old..new 状态。但是,它不知道整个分支集合,因此如果天真地使用它,最终会为每个引用触发一封电子邮件。 post-receive 钩子更适合这样做。

在将用户的访问权限仅限于通过线路传输的 git 命令的环境中,此钩子可用于实现访问控制,而无需依赖文件系统所有权和组成员身份。有关如何使用登录 shell 来限制用户对 git 命令的访问权限,请参阅 git-shell[1]

标准输出和标准错误输出都会转发到另一端的 git send-pack,因此您可以简单地 echo 消息给用户。

默认的 update 钩子在启用时,并且在未设置或设置为 false 的情况下,使用 hooks.allowunannotated 配置选项,会阻止推送未注释的标签。

proc-receive

此钩子由 git-receive-pack[1] 调用。如果服务器设置了多值配置变量 receive.procReceiveRefs,并且发送到 *receive-pack* 的命令具有匹配的引用名称,则这些命令将由此钩子执行,而不是由内部 execute_commands() 函数执行。此钩子负责更新相关引用并将结果报告回 *receive-pack*。

此钩子为接收操作执行一次。它不带任何参数,但使用 pkt-line 格式协议与 *receive-pack* 通信,以读取命令、推送选项并发送结果。在以下协议示例中,字母 *S* 代表 *receive-pack*,字母 *H* 代表此钩子。

# 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 results 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' 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

proc-receive 钩子的每个命令都可能指向一个伪引用,并且始终具有零 old-oid 作为其 old-oid,而 *proc-receive* 钩子可能会更新一个备用引用,并且该备用引用可能已经存在,并且具有非零 old-oid。对于这种情况,此钩子将使用“option”指令来报告前导“ok”指令给出的引用的扩展属性。

此钩子的命令报告应与输入的顺序相同。*proc-receive* 钩子的退出状态仅决定发送给它的命令组的成功或失败,除非正在使用原子推送。

post-receive

git-receive-pack[1]git push 做出反应并在其存储库中更新引用时,会调用此钩子。在处理完所有建议的引用更新之后,并且如果作为结果至少更新了一个引用,则该钩子在远程存储库上执行一次。

该钩子不带任何参数。它在标准输入上接收一行,对应于每个成功更新的引用,格式与 pre-receive 钩子相同。

此钩子不会影响 git receive-pack 的结果,因为它是在实际工作完成后调用的。

这取代了 post-update 钩子,因为它除了引用名称之外,还获取了所有引用的旧值和新值。

标准输出和标准错误输出都会转发到另一端的 git send-pack,因此您可以简单地 echo 消息给用户。

默认的 post-receive 钩子为空,但在 Git 发行版的 contrib/hooks 目录中提供了一个示例脚本 post-receive-email,该脚本实现了发送提交电子邮件。

可以使用环境变量 GIT_PUSH_OPTION_COUNT 读取 git push --push-option=... 命令行上给定的推送选项的数量,这些选项本身可以在 GIT_PUSH_OPTION_0, GIT_PUSH_OPTION_1,… 中找到。如果协商不使用推送选项阶段,则不会设置环境变量。如果客户端选择使用推送选项,但未传输任何选项,则计数变量将设置为零,GIT_PUSH_OPTION_COUNT=0

有关更多详细信息,请参阅 git-receive-pack[1] 中的“post-receive”部分。

post-update

git-receive-pack[1]git push 做出反应并在其存储库中更新引用时,会调用此钩子。它在所有引用都已更新后在远程存储库上执行一次。

它采用可变数量的参数,每个参数都是实际更新的引用的名称。

此钩子主要用于通知,并且不能影响 git receive-pack 的结果。

post-update 钩子可以知道推送了哪些头,但它不知道它们的原始值和更新值,因此它不是进行 log old..new 的好地方。 post-receive 钩子确实获得了引用的原始值和更新值。如果您需要它们,您可以考虑使用它。

启用后,默认的 post-update 钩子运行 git update-server-info 以保持哑传输(例如,HTTP)使用的信息为最新。如果您正在发布可以通过 HTTP 访问的 Git 存储库,则可能应该启用此钩子。

标准输出和标准错误输出都会转发到另一端的 git send-pack,因此您可以简单地 echo 消息给用户。

reference-transaction

任何执行引用更新的 Git 命令都会调用此钩子。每当准备、提交或中止引用事务时,它都会执行,因此可能会被多次调用。该钩子还支持符号引用更新。

该钩子正好接受一个参数,该参数是给定引用事务的当前状态

  • "prepared": 所有引用更新都已排队到事务中,并且引用已锁定在磁盘上。

  • "committed": 引用事务已提交,并且所有引用现在都具有它们各自的新值。

  • "aborted": 引用事务已中止,未执行任何更改,并且已释放锁定。

对于添加到事务的每个引用更新,该钩子在标准输入上接收以下格式的一行

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

其中 <old-value> 是传递到引用事务中的旧对象名称,<new-value> 是要存储在引用中的新对象名称,而 <ref-name> 是引用的完整名称。无论其当前值如何,都要强制更新引用,或者要全新创建引用时,<old-value> 是全零对象名称。为了区分这些情况,您可以检查 <ref-name> 的当前值 通过 git rev-parse

对于符号引用更新,<old_value><new-value> 字段可以表示引用而不是对象。引用将使用 ref: 前缀表示,例如 ref:<ref-target>

对于除“prepared”状态之外的任何状态,都会忽略钩子的退出状态。在“prepared”状态下,非零退出状态将导致事务中止。在这种情况下,不会使用“aborted”状态调用该钩子。

push-to-checkout

这个钩子在 git push 操作导致远程仓库中的引用更新,并且推送尝试更新当前检出的分支,同时 receive.denyCurrentBranch 配置变量被设置为 updateInstead 时,由 git-receive-pack[1] 调用。默认情况下,如果远程仓库的工作树和索引与当前检出的提交有任何差异,这样的推送会被拒绝;当工作树和索引都与当前提交匹配时,它们会被更新为与新推送的分支顶端匹配。这个钩子用于覆盖默认行为。

该钩子接收即将用于更新当前分支顶端的提交。它可以以非零状态退出以拒绝推送(这样做时,它不得修改索引或工作树)。或者,它可以对工作树和索引进行任何必要的更改,使其在当前分支顶端更新到新提交时达到期望的状态,并以零状态退出。

例如,钩子可以简单地运行 git read-tree -u -m HEAD "$1",以模拟 git push 反向运行的 git fetch,因为双树形式的 git read-tree -u -m 本质上与 git switchgit checkout 相同,它们在切换分支的同时保留工作树中与分支差异不冲突的本地更改。

pre-auto-gc

此钩子由 git gc --auto 调用(参见 git-gc[1])。它不接受任何参数,如果此脚本以非零状态退出,则会导致 git gc --auto 中止。

post-rewrite

此钩子由重写提交的命令调用(git-commit[1] 在使用 --amend 调用时和 git-rebase[1];但是,像 git-fast-import[1]git-filter-repo 这样的完整历史(重写)工具通常不调用它!)。它的第一个参数表示调用它的命令:目前是 amendrebase 之一。将来可能会传入更多依赖于命令的参数。

该钩子从 stdin 接收重写提交的列表,格式如下:

<old-object-name> SP <new-object-name> [ SP <extra-info> ] LF

extra-info 再次依赖于命令。如果它是空的,则前面的 SP 也被省略。目前,没有命令传递任何 extra-info

钩子总是在自动注释复制(参见 git-config[1] 中的 "notes.rewrite.<command>")发生之后运行,因此可以访问这些注释。

以下命令特定的注释适用

rebase

对于 squashfixup 操作,所有被压缩的提交都被列为被重写为压缩后的提交。这意味着会有多行共享相同的 new-object-name

保证提交按照 rebase 处理的顺序被列出。

sendemail-validate

此钩子由 git-send-email[1] 调用。

它接受这些命令行参数。它们是,1. 保存要发送的电子邮件内容的文件名。2. 保存电子邮件的 SMTP 标头的文件名。

SMTP 标头的传递方式与传递给用户的邮件传输代理 (MTA) 的方式完全相同。实际上,提供给用户的 MTA 的电子邮件是 $2 的内容,后跟 $1 的内容。

下面显示了一些常见标头的示例。请注意大小写和多行制表结构。

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

以非零状态退出会导致 git send-email 在发送任何电子邮件之前中止。

执行钩子时设置以下环境变量。

GIT_SENDEMAIL_FILE_COUNTER

一个从 1 开始的计数器,对于每个包含要发送的电子邮件的文件(不包括任何 FIFO)递增 1。此计数器不遵循补丁系列计数器方案。它将始终从 1 开始,到 GIT_SENDEMAIL_FILE_TOTAL 结束。

GIT_SENDEMAIL_FILE_TOTAL

将要发送的文件总数(不包括任何 FIFO)。此计数器不遵循补丁系列计数器方案。它将始终等于正在发送的文件数,无论是否有封面信。

这些变量可以用于验证补丁系列。

Git 附带的示例 sendemail-validate 钩子检查所有发送的补丁(不包括封面信)是否可以在不冲突的情况下应用于上游存储库的默认分支。一些占位符留给在给定系列的所有补丁都应用后执行的附加验证步骤。

fsmonitor-watchman

当配置选项 core.fsmonitor 设置为 .git/hooks/fsmonitor-watchman.git/hooks/fsmonitor-watchmanv2 时,将调用此钩子,具体取决于要使用的钩子版本。

版本 1 接受两个参数,一个版本 (1) 和自 1970 年 1 月 1 日午夜以来经过的纳秒数。

版本 2 接受两个参数,一个版本 (2) 和一个用于标识自令牌以来的更改的令牌。对于 watchman,这将是一个时钟 ID。此版本必须将新令牌输出到 stdout,后跟一个 NUL,然后是文件列表。

钩子应将自请求时间以来工作目录中可能已更改的所有文件列表输出到 stdout。逻辑应该是包含性的,这样它就不会错过任何潜在的更改。路径应相对于工作目录的根目录,并用单个 NUL 分隔。

包含实际上没有更改的文件是可以的。所有更改,包括新创建和已删除的文件,都应包括在内。当文件重命名时,应包括旧名称和新名称。

Git 将根据给定的路径名限制它检查更改的文件以及检查未跟踪文件的目录。

告诉 git "所有文件都已更改" 的一种优化方法是返回文件名 /

退出状态决定 git 是否会使用钩子中的数据来限制其搜索。如果出错,它将回退到验证所有文件和文件夹。

p4-changelist

此钩子由 git-p4 submit 调用。

在用户编辑完变更列表消息后,将执行 p4-changelist 钩子。可以使用 --no-verify 选项绕过它。它接受一个参数,即保存建议的变更列表文本的文件名。以非零状态退出会导致命令中止。

允许该钩子编辑变更列表文件,并可用于将文本规范化为某些项目标准格式。它还可以用于在检查消息文件后拒绝提交。

运行 git-p4 submit --help 了解详细信息。

p4-prepare-changelist

此钩子由 git-p4 submit 调用。

p4-prepare-changelist 钩子在准备好默认变更列表消息后,在启动编辑器之前立即执行。它接受一个参数,即包含变更列表文本的文件名。如果脚本以非零状态退出,将中止该过程。

该钩子的目的是就地编辑消息文件,并且不会被 --no-verify 选项抑制。即使设置了 --prepare-p4-only,也会调用此钩子。

运行 git-p4 submit --help 了解详细信息。

p4-post-changelist

此钩子由 git-p4 submit 调用。

在 P4 中成功提交后,将调用 p4-post-changelist 钩子。它不接受任何参数,主要用于通知,不会影响 git p4 提交操作的结果。

运行 git-p4 submit --help 了解详细信息。

p4-pre-submit

此钩子由 git-p4 submit 调用。它不接受任何参数,也不从标准输入接收任何内容。如果此脚本以非零状态退出,则会阻止 git-p4 submit 启动。可以使用 --no-verify 命令行选项绕过它。运行 git-p4 submit --help 了解详细信息。

post-index-change

在 read-cache.c do_write_locked_index 中写入索引时,将调用此钩子。

传递给钩子的第一个参数是用于指示工作目录是否正在更新的指示符。"1" 表示工作目录已更新,"0" 表示工作目录未更新。

传递给钩子的第二个参数是指示索引是否已更新以及 skip-worktree 位是否可能已更改的指示符。"1" 表示 skip-worktree 位可能已更新,"0" 表示它们未更新。

运行钩子时,只能将一个参数设置为 "1"。运行传递 "1"、"1" 的钩子是不可能的。

SEE ALSO

GIT

Part of the git[1] suite

scroll-to-top