服务器钩子

Git 支持在不同操作上执行的钩子。这些钩子在服务器上运行,可用于强制执行特定的提交策略或根据仓库的状态执行其他任务。

Git 支持以下钩子:

  • pre-receive
  • post-receive
  • update

有关每种钩子类型的更多信息,请参阅 Git 文档

服务器端 Git 钩子可以配置为:

为单个仓库创建一个服务器钩子

如果您不使用哈希存储,则项目的仓库目录可能与以下说明不完全匹配。在这种情况下:

  • 对于从源代码安装,路径通常是 /home/git/repositories/<group>/<project>.git
  • 对于 Omnibus GitLab 安装,路径通常是 /var/opt/gitlab/git-data/repositories/<group>/<project>.git

按照以下步骤为仓库设置服务器端钩子:

  1. 进入管理中心 > 项目并选择要添加服务器钩子的项目。
  2. 在出现的页面上找到 Gitaly 相对路径。这是必须实现服务器钩子的地方。有关解释相对路径的信息,请参阅转换哈希存储路径
  3. 在文件系统上,在此位置创建一个名为 custom_hooks 的新目录。
  4. 在新的 custom_hooks 目录中,创建一个名称与钩子类型匹配的文件。例如,对于 pre-receive 钩子,文件名应该是不带扩展名的pre-receive
  5. 使钩子文件可执行并确保它为 Git 用户所有。
  6. 编写代码,使服务端钩子功能如预期。钩子可以是任何语言。确保顶部的 “shebang” 正确反映语言类型。例如,如果脚本是用 Ruby 编写的,shebang 可能是 #!/usr/bin/env ruby​​

假设钩子代码被正确地实现,钩子代码被适当地执行。

为所有仓库创建一个全局服务器钩子

要创建适用于实例中所有仓库的 Git 钩子,请设置全局服务器钩子。默认的全局服务器钩子目录在 GitLab Shell 目录中。在那里添加的任何钩子都适用于所有仓库,包括:

  • 项目和组 wiki 仓库,其存储目录名称的格式为<id>.wiki.git

  • 设计管理项目下的仓库,其存储目录名称格式为<id>.design.git

默认目录:

  • 对于从源代码安装通常是 /home/git/gitlab-shell/hooks
  • 对于 Omnibus GitLab 安装通常是 /opt/gitlab/embedded/service/gitlab-shell/hooks

要为全局服务器钩子使用不同的目录,请在 Gitaly 配置中设置 custom_hooks_dir

  • 对于 Omnibus 安装,在 gitlab.rb 中设置。
  • 对于源码安装,配置位置取决于 GitLab 版本。为了:
    • 13.0 及更早版本,在gitlab-shell/config.yml 中设置。
    • 13.1 及更高版本,在 [hooks] 部分下的 gitaly/config.toml 中设置。
note如果 gitaly/config.toml 中的值为空或不存在,gitlab-shell/config.yml 中的 custom_hooks_dir 值在 13.1 及更高版本中仍然有效。

按照以下步骤为所有仓库设置全局服务器钩子:

  1. 在 GitLab 服务器上,导航到配置的全局服务器钩子目录。
  2. 在此位置创建一个新目录。根据钩子的类型,它可以是 pre-receive.dpost-receive.dupdate.d 目录。
  3. 在这个新目录中,添加您的钩子。钩子可以是任何语言。确保顶部的 “shebang” 正确反映语言类型。例如,如果脚本是用 Ruby 编写的,shebang 可能是 #!/usr/bin/env ruby
  4. 使钩子文件可执行并确保它为 Git 用户所有。

现在测试钩子以检查它是否正常工作。

链式钩子

每个项目全局设置的服务器挂钩可以在链中执行。

服务器钩子按以下优先级顺序搜索和执行:

  • 内置 GitLab 服务器钩子。这些不是用户可定制的。
  • <project>.git/custom_hooks/<hook_name>:每个项目的钩子。这是为了向后兼容而保留的。
  • <project>.git/custom_hooks/<hook_name>.d/*:每个项目钩子的位置。
  • <custom_hooks_dir>/<hook_name>.d/*:除编辑器备份文件之外的所有可执行全局钩子文件的位置。

在目录中,服务器钩子:

  • 按字母顺序执行。
  • 当钩子以非零值退出时停止执行。

<hook_name>.d 必须是 pre-receive.dpost-receive.dupdate.d 才能正常工作。任何其它名称都将被忽略。

.d 目录中的文件必须是可执行的并且不匹配备份文件模式 (*~)。

对于 <project>.git,您需要将项目名称转换为 GitLab 使用的哈希存储格式。

环境变量

以下一组环境变量可用于服务器钩子。

环境变量 描述
GL_ID 发起推送的用户的 GitLab 标识符。例如,user-2234
GL_PROJECT_PATH GitLab 项目路径
GL_PROTOCOL 用于此更改的协议。其中之一:http(使用 HTTP 的 Git 推送)、ssh(使用 SSH 的 Git 推送)或 web(所有其他操作)。
GL_REPOSITORY project-<id> 其中 id 是项目的 ID
GL_USERNAME 发起推送的用户的 GitLab 用户名

Pre-receive 和 post-receive 服务器钩子也可以访问以下 Git 环境变量。

环境变量 描述
GIT_ALTERNATE_OBJECT_DIRECTORIES 隔离环境中的备用对象目录。请参阅 Git receive-pack 文档
GIT_OBJECT_DIRECTORY 隔离环境中的 GitLab 项目路径。请参阅 Git receive-pack 文档
GIT_PUSH_OPTION_COUNT 推送选项的数量。 请参阅 Git pre-receive 文档
GIT_PUSH_OPTION_<i> 推送选项的值,其中i0GIT_PUSH_OPTION_COUNT - 1。 请参阅 Git pre-receive 文档
note虽然可以将其他环境变量传递给服务器钩子,但您的应用程序不应依赖它们,因为它们会发生变化。

自定义错误消息

要在提交被拒绝,或 Git 挂钩期间发生错误时在 GitLab UI 中显示自定义错误消息,您的脚本应该:

  • 将自定义错误消息发送到脚本的 stdoutstderr
  • GL-HOOK-ERR: 作为每条消息的前缀,前缀前没有任何字符。

自定义错误消息示例

这个用 Bash 编写的钩子脚本在 GitLab UI 中生成以下消息:

#!/bin/sh
echo "GL-HOOK-ERR: My custom error message.";
exit 1

Custom message from custom Git hook