Git Hooks 小记
了解 Git hooks 的用法。
Git hook
Git hooks 是 Git 提供的功能。Git hooks 分为客户端 hook 和服务器端 hook。
客户端钩子由诸如提交和合并这样的操作所调用,而服务器端钩子作用于诸如接收被推送的提交这样的联网操作
钩子都被存储在 Git 目录下的 hooks 子目录中。 也即绝大部分项目中的 .git/hooks 。 当你用 git init 初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本。 这些脚本除了本身可以被调用外,它们还透露了被触发时所传入的参数。 所有的示例都是 shell 脚本,其中一些还混杂了 Perl 代码,不过,任何正确命名的可执行脚本都可以正常使用 —— 你可以用 Ruby 或 Python,或任何你熟悉的语言编写它们。 这些示例的名字都是以 .sample 结尾,如果你想启用它们,得先移除这个后缀。
常用钩子如下:
pre-commit
- 在键入提交信息前运行。 它用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。 如果该钩子以非零值退出,Git 将放弃此次提交,不过你可以用 git commit –no-verify 来绕过这个环节。pre-receive
- 处理来自客户端的推送操作时,最先被调用的脚本是 pre-receive。 它从标准输入获取一系列被推送的引用。如果它以非零值退出,所有的推送内容都不会被接受。 你可以用这个钩子阻止对引用进行非快进(non-fast-forward)的更新,或者对该推送所修改的所有引用和文件进行访问控制
客户端钩子的使用非常简单。在工程的 .git/hooks
目录中可以找到许多内置的钩子。
这是一个 commit-msg
钩子。内容如下:
1 |
|
默认的客户端 hook 是放在 .git/hooks/ 目录下,所以不受版本控制。
我们可以将客户端 hook 纳入到版本控制中。在根目录中新建 .githooks
目录,目录中放 hook 脚本,然后执行如下命令:
1 | git config core.hooksPath .githooks |
服务器端的钩子也是类似方法来配置。Gitlab 支持 Server hooks
GitLab administrators configure server hooks on the file system of the GitLab server. If you don’t have file system access, alternatives to server hooks include:
- Webhooks
- GitLab CI/CD
- Push rules, for a user-configurable Git hook interface.
不过,公司的git服务器由专人管理,我们通常无权限随意修改服务端的钩子。Gitlab 提供的其他可替代方案包括:Webhooks、GitLab CI/CD、Push rules
Push rules 机制,允许用户为自己的项目设备 pre-receive
钩子。
Push rules are pre-receive Git hooks you can enable in a user-friendly interface. Push rules give you more control over what can and can’t be pushed to your repository.
不过,这个功能只在 Gitlab Premium 版本中提供,Gitlab CE 版本中不支持。很不幸,我们公司使用的是 Gitlab CE 版本。
总结
- 钩子(hook)是 Git 提供的功能,它跟 Github、Gitlab 或 Gogs 无关
- 钩子分客户端钩子和服务器端钩子
- Gitlab 支持 Server hooks。不过 Serve hooks 一般只有系统管理员才有权限操作
- Gitlab Premium 版本支持 Push Rules (即
pre-receive
) - Gitlab CE 版本不支持 Push Rules
- Gitlab CE 版本中 Push Rules 的最佳替代方案是 GitLab CI/CD
- 可以通过
git config core.hooksPath <path>
调整钩子目录来将钩子纳入到版本管理中来