在您的工作离开计算机之前,使用 Git hooks 检查您的工作
Git 挂钩是 Git 在固定时刻自行运行的脚本,例如在提交或推送之前。在 Preferences › Hooks 中,GitTree 显示何时运行的内容,允许您从现成的模板添加挂钩、编辑和测试运行它们、关闭和打开它们,并通过存储库与您的团队共享它们。
适用于 GitTree 免费:所有本地 Git 功能,无需帐户。
开始之前
- 存储库已打开:挂钩属于一个存储库。
- 该存储库是可信的。在受限模式下,Git 不运行任何钩子;您仍然可以阅读和编辑它们(存储库信任)。
- Hook 是 shell 脚本。这些模板使用普通的
sh,其中 macOS、Windows(通过 Git for Windows)和 Linux 均提供。
在哪里可以找到它
- 提交框:在提交按钮下,May run: … 列出了提交运行的挂钩。 Manage Hooks 打开页面。
- 工具栏中的 Tools,或左侧面板的 TOOLS 部分:Git hooks。
- 存储库选项卡的菜单或命令面板:Manage Git Hooks… 或
Alt+Shift+H。 - Preferences (
Mod+,) › Hooks。在首选项中搜索“hooks”、“pre-commit”或“husky”也可以找到它。
| 行动 | macOS | Windows 和 Linux |
|---|---|---|
| Manage Git hooks | ⌥⇧H | Alt+Shift+H |
| Open Preferences | ⌘, | Ctrl+, |
步骤
打开挂钩页面
使用提交按钮下的 Manage Hooks 或
Alt+Shift+H。打开多个存储库后,在 Repository 中选择一个。该页面首先介绍了钩子是什么、三步 How it works 指南和本文的链接。添加一个钩子
按 Add Hook…。在 When it runs 下,选择钩子;在 Start from 下,选择一个模板:Git’s sample 或 Empty script。 Script 预览准确显示了将要写入的内容。 Create Hook 写入文件,准备运行,并在编辑器中打开它。
编辑脚本
Edit 打开带有行号的脚本。更改它并按 Save(或
Mod+S)。如果文件在您打开后在磁盘上发生了更改,则 GitTree 会拒绝覆盖它并保留您的文本,以便您可以重新打开并进行比较。试运行一下
Test Run 现在按照 Git 的方式运行挂钩,无需进行提交或推送。对于 commit-msg 和 prepare-commit-msg,键入要检查的消息。输出流入,结果表明 Git 会做什么: Passed with exit code 0: Git would continue. 或 Failed with exit code 1: Git would stop here. Stop 结束长时间运行。
关闭挂钩或共享它们
挂钩旁边的开关可以通过将其重命名为
<name>.disabled将其关闭,然后再次打开;没有删除任何内容。 Share Through .githooks 将挂钩放入您团队的存储库中(见下文)。
预期结果
从下一次提交或推送开始,Git 会运行标记为 Runs 的挂钩。提交框的 May run: … 行为它们命名,当打印某些内容或停止提交时,挂钩的输出出现在 Hook output 下。
什么是钩子以及为什么使用它们
Git 在 hooks 文件夹中查找具有固定名称的可执行文件(.git/hooks,除非 core.hooksPath 另有说明),并在匹配的时刻运行它们。在操作之前运行的挂钩(例如 pre-commit 或 pre-push)可以通过以非零状态退出来停止操作。在其之后运行的挂钩(例如 post-commit 或 post-merge)只能报告。
- 在错误离开您的计算机之前捕获它们:失败的测试、lint 错误、剩余的冲突标记和过大的文件。
- 保持提交消息一致,例如每条消息中的 Conventional Commits 或问题键。
- 在几秒钟内获得反馈,而不是等待 CI 运行失败。
- 通过将挂钩保留在存储库中,为整个团队提供相同的检查。
您最常使用的钩子
| 钩子 | 当 Git 运行它时 | 典型用途 |
|---|---|---|
| pre-commit | 创建提交之前 | 对所暂存的内容进行 Lint 和快速测试;在 main 上阻止提交 |
| prepare-commit-msg | 在写入消息之前 | 将分支名称中的问题密钥放入消息中 |
| commit-msg | 消息写入后 | 检查消息格式,例如Conventional Commits |
| post-commit | 创建提交后 | 通知或记录;无法撤消提交 |
| pre-push | 在将任何内容发送到远程之前 | 运行完整的测试套件;拒绝推送到受保护的分支 |
| post-merge | 合并或拉取后 | 假设锁定文件发生更改,因此依赖项会重新安装 |
| post-checkout | 切换分支后 | 清理构建输出或刷新生成的文件 |
服务器挂钩(例如 pre-receive 和 update)仅在接收推送的服务器上运行。 GitTree 在它们存在时列出它们,但从不测试运行它们。
现成的模板
| 模板 | 钩子 | 它的作用 |
|---|---|---|
| 保护主要分支 | pre-commit | 停止直接在 main 或 master 上进行的提交 |
| 捕获冲突标记和空白 | pre-commit | 停止添加剩余冲突标记或尾随空格 (git diff --cached --check) 的提交 |
| 阻止大文件 | pre-commit | 停止添加大于 5 MB 的文件的提交 |
| 添加问题密钥 | prepare-commit-msg | 以分支名称中的问题键开始每条消息,例如 ABC-123 |
| Conventional Commits | commit-msg | 需要摘要,例如 feat(parser): accept empty lines |
| 在推送之前运行测试 | pre-push | 运行 npm test、cargo test、go test、pytest 或 make test,并在失败时停止推送 |
| 保护远程分支 | pre-push | 停止直接推送到远程仓库上的主站或主站 |
| 依赖性提醒 | post-merge | 表示拉取或合并后锁定文件发生更改 |
每个模板都是一个普通脚本,其设置位于顶部,例如 PROTECTED="main master" 或 TEST_COMMAND=""。在编辑器中更改它们以适合您的项目。
测试运行的作用
GitTree 通过 git hook run 运行钩子,因此 Git 会像在实际操作期间一样查找并启动它,包括 core.hooksPath。钩子获取虚构的输入:
- pre-commit、pre-merge-commit、post-commit 和 pre-auto-gc:无参数。
- commit-msg 和 prepare-commit-msg:包含您键入的消息的临时文件,随后删除。
- pre-push:您的推送远程仓库的名称和 URL,其输入中没有分支。
- post-merge:
0,与正常合并后一样。
与您的团队分享 hooks
.git/hooks 中的挂钩永远不会提交,因此每个克隆都有自己的挂钩。 Share Through .githooks 将它们复制到存储库中的 .githooks 文件夹中,并在此存储库的配置中将其设置为 core.hooksPath。提交文件夹;每个队友在克隆后运行一次:
git config core.hooksPath .githooksUse This Clone’s Own Hooks 再次删除该设置。 .githooks 文件夹和 .git/hooks 中的挂钩保持在原来的位置。
跳过一次提交的钩子
在提交框中打开 Commit Options 并启用 Skip Hooks (--no-verify)。然后 Git 会跳过该提交的 pre-commit 和 commit-msg; prepare-commit-msg 和 post-commit 仍在运行,提交按钮下方的行也是如此。要使挂钩停止更长时间,请在“挂钩”页面上将其关闭。
如果出现问题
挂钩显示 Not executable 并且从不运行。
在 macOS 和 Linux 上,Git 会跳过没有执行权限的挂钩文件。按Make Executable; GitTree 仅在文件可读的位置添加它。
“自从打开后,磁盘上的挂钩发生了变化;重新打开它以查看新内容。”
另一个程序或挂钩管理器重写了该文件。关闭编辑器,再次打开它,然后将更改应用到新内容。
“这个钩子是一个链接。GitTree 永远不会通过链接写入;编辑它指向的文件。”
挂钩是一个符号链接,通常由挂钩管理器创建。编辑它指向的文件或该工具的配置。
该脚本在 macOS 上运行,但在 Linux 上失败,并出现“错误解释器”或 \
错误。
该文件有 Windows 行结尾 (CRLF)。编辑对它们发出警告;保存以 LF 行结尾的脚本。
Test Run 呈灰色。
它的原因就在按钮旁边:信任存储库,打开钩子,使其可执行,或者注意这个钩子仅在真正的 Git 操作期间接收输入。
问题
Hooks 是免费计划的一部分吗?
是的。管理、编辑、测试运行和共享挂钩是本地 Git,不需要托管帐户。
当我关闭挂钩时,GitTree 会删除它吗?
否。关闭会将文件重命名为 <name>.disabled;打开后会将其重命名回来。 GitTree 永远不会删除挂钩。
我创建的钩子会被提交吗?
不在 .git/hooks 中。使用 Share Through .githooks 将挂钩保留在存储库中,它们像任何其他文件一样提交。
钩子可以用 Node.js 或 Python 编写吗?
是的。 Git 运行文件,程序在第一行,例如 #!/usr/bin/env node;编辑器将该程序显示为 Runs with node。该程序必须安装在运行该挂钩的每台计算机上。
