-
1. 起步
-
2. Git 基础
-
3. Git 分支
-
4. 服务器上的 Git
- 4.1 协议
- 4.2 在服务器上部署 Git
- 4.3 生成 SSH 公钥
- 4.4 架设服务器
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方托管服务
- 4.10 小结
-
5. 分布式 Git
-
A1. 附录 A: Git 在其他环境
- A1.1 图形界面
- A1.2 Visual Studio 中的 Git
- A1.3 Visual Studio Code 中的 Git
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git
- A1.5 Sublime Text 中的 Git
- A1.6 Bash 中的 Git
- A1.7 Zsh 中的 Git
- A1.8 PowerShell 中的 Git
- A1.9 小结
-
A2. 附录 B: 在应用程序中嵌入 Git
-
A3. 附录 C: Git 命令
8.3 自定义 Git - Git 钩子
Git 钩子
与许多其他版本控制系统一样,Git 也有在特定重要操作发生时触发自定义脚本的方式。这些钩子分为两组:客户端钩子和服务器端钩子。客户端钩子由诸如提交和合并等操作触发,而服务器端钩子则在诸如接收推送提交等网络操作上运行。你可以出于各种原因使用这些钩子。
安装钩子
所有钩子都存储在 Git 目录的 `hooks` 子目录中。在大多数项目中,它位于 `.git/hooks`。当你使用 `git init` 初始化一个新仓库时,Git 会用许多示例脚本填充 `hooks` 目录,其中许多脚本本身就很有用;它们也记录了每个脚本的输入值。所有示例都写成 shell 脚本,并混入了一些 Perl,但任何命名正确的、可执行的脚本都能正常工作——你可以用 Ruby、Python 或你熟悉的任何语言编写它们。如果你想使用捆绑的钩子脚本,你需要重命名它们;它们的文件名都以 `.sample` 结尾。
要启用一个钩子脚本,请在你的 `.git` 目录的 `hooks` 子目录中放置一个命名合适(不带任何扩展名)且可执行的文件。从那时起,它就应该被调用。我们将在此处介绍大多数主要的钩子文件名。
客户端钩子
客户端钩子有很多。本节将它们分为提交工作流钩子、电子邮件工作流脚本和其他所有钩子。
|
注意
|
重要提示:当你克隆仓库时,客户端钩子不会被复制。如果你的这些脚本旨在强制执行策略,你可能需要在服务器端进行;请参阅Git 强制策略示例中的示例。 |
提交工作流钩子
前四个钩子与提交过程有关。
`pre-commit` 钩子首先运行,甚至在你输入提交消息之前。它用于检查即将提交的快照,看看你是否遗漏了什么,确保测试运行,或检查代码中你需要检查的任何内容。此钩子以非零退出会中止提交,尽管你可以使用 `git commit --no-verify` 绕过它。你可以做一些事情,比如检查代码风格(运行 `lint` 或类似工具),检查尾随空格(默认钩子正是这样做的),或检查新方法上的适当文档。
`prepare-commit-msg` 钩子在提交消息编辑器启动之前但在默认消息创建之后运行。它允许你在提交作者看到默认消息之前编辑它。此钩子接受几个参数:包含到目前为止提交消息的文件路径、提交类型以及(如果这是修改提交)提交的 SHA-1。此钩子通常不适用于普通提交;相反,它适用于默认消息自动生成的提交,例如模板提交消息、合并提交、压缩提交和修改提交。你可以将其与提交模板结合使用,以编程方式插入信息。
`commit-msg` 钩子接受一个参数,它仍然是包含开发人员编写的提交消息的临时文件的路径。如果此脚本以非零退出,Git 将中止提交过程,因此你可以使用它在允许提交通过之前验证你的项目状态或提交消息。在本章的最后一节,我们将演示如何使用此钩子检查你的提交消息是否符合所需的模式。
整个提交过程完成后,`post-commit` 钩子运行。它不接受任何参数,但你可以通过运行 `git log -1 HEAD` 轻松获取最后一次提交。通常,此脚本用于通知或类似用途。
电子邮件工作流钩子
你可以为基于电子邮件的工作流设置三个客户端钩子。它们都由 `git am` 命令调用,因此如果你在工作流中不使用该命令,可以安全地跳到下一节。如果你通过 `git format-patch` 准备的电子邮件接收补丁,那么其中一些可能对你有帮助。
首先运行的钩子是 `applypatch-msg`。它接受一个参数:包含提议的提交消息的临时文件的名称。如果此脚本以非零退出,Git 将中止补丁。你可以使用它来确保提交消息格式正确,或通过让脚本就地编辑来规范消息。
通过 `git am` 应用补丁时运行的下一个钩子是 `pre-applypatch`。有点令人困惑的是,它是在补丁应用之后但在提交之前运行的,因此你可以使用它在提交之前检查快照。你可以使用此脚本运行测试或以其他方式检查工作树。如果缺少某些内容或测试不通过,以非零退出将中止 `git am` 脚本而不提交补丁。
`git am` 操作期间运行的最后一个钩子是 `post-applypatch`,它在提交完成后运行。你可以使用它通知组或补丁作者你已拉取了补丁。你无法用此脚本停止补丁过程。
其他客户端钩子
`pre-rebase` 钩子在重新设置任何内容之前运行,并且可以通过以非零退出而停止该过程。你可以使用此钩子不允许重新设置任何已推送的提交。Git 安装的示例 `pre-rebase` 钩子就是这样做的,尽管它做出了一些可能与你的工作流不符的假设。
`post-rewrite` 钩子由替换提交的命令运行,例如 `git commit --amend` 和 `git rebase`(但不包括 `git filter-branch`)。它的唯一参数是触发重写的命令,并通过 `stdin` 接收重写列表。此钩子与 `post-checkout` 和 `post-merge` 钩子有许多相同的用途。
成功运行 `git checkout` 后,`post-checkout` 钩子运行;你可以使用它为你的项目环境正确设置工作目录。这可能意味着移动你不希望源代码控制的大型二进制文件、自动生成文档或类似的事情。
`post-merge` 钩子在成功的 `merge` 命令后运行。你可以使用它来恢复 Git 无法跟踪的工作树中的数据,例如权限数据。此钩子同样可以验证 Git 控制之外的文件是否存在,你可能希望在工作树更改时将它们复制进去。
`pre-push` 钩子在 `git push` 期间运行,在远程引用更新之后但在任何对象传输之前。它接收远程的名称和位置作为参数,并通过 `stdin` 接收待更新引用的列表。你可以使用它在推送发生之前验证一组引用更新(非零退出代码将中止推送)。
Git 有时会作为其正常操作的一部分进行垃圾回收,通过调用 `git gc --auto`。`pre-auto-gc` 钩子在垃圾回收发生之前被调用,可用于通知你正在发生此操作,或在现在不是好时机时中止回收。
服务器端钩子
除了客户端钩子之外,你还可以使用几个重要的服务器端钩子作为系统管理员来为你的项目强制执行几乎任何类型的策略。这些脚本在推送服务器之前和之后运行。`pre` 钩子可以随时以非零退出以拒绝推送并向客户端打印错误消息;你可以设置一个你希望的复杂程度的推送策略。
pre-receive
处理来自客户端的推送时运行的第一个脚本是 `pre-receive`。它从标准输入接收正在推送的引用列表;如果它以非零退出,则不接受任何引用。你可以使用此钩子执行诸如确保所有更新的引用都不是非快进式操作,或对所有引用及其通过推送修改的文件进行访问控制。
update
`update` 脚本与 `pre-receive` 脚本非常相似,不同之处在于它为推送者尝试更新的每个分支运行一次。如果推送者尝试推送到多个分支,`pre-receive` 只运行一次,而 `update` 为他们推送的每个分支运行一次。此脚本不从标准输入读取,而是接受三个参数:引用(分支)的名称、推送前该引用指向的 SHA-1,以及用户尝试推送的 SHA-1。如果 `update` 脚本以非零退出,则只拒绝该引用;其他引用仍然可以更新。
post-receive
`post-receive` 钩子在整个过程完成后运行,可用于更新其他服务或通知用户。它接受与 `pre-receive` 钩子相同的标准输入数据。示例包括向列表发送电子邮件、通知持续集成服务器或更新工单跟踪系统——你甚至可以解析提交消息以查看是否需要打开、修改或关闭任何工单。此脚本不能停止推送过程,但客户端在它完成之前不会断开连接,因此如果你尝试做任何可能需要很长时间的事情,请务必小心。
|
提示
|
如果你正在编写其他人需要阅读的脚本/钩子,请优先使用命令行标志的完整版本;六个月后你就会感谢我们。 |