TL;DR
Git 钩子
本文深入讲解 Git 钩子的工作原理及实际应用,包括 pre-receive、update 和 post-receive 三种服务端钩子的特点与用途。通过流程图和实例分析,展示了 Git 推送过程中钩子的触发顺序和环境变量的作用,为开发者提供自定义 Git 工作流的技术指南。
Git Hooks#

默认钩子模板:
$ ls /usr/share/git-core/templates/branches description hooks info有一些比较重要的底层命令,如:
当我们在客户端执行 git push 时,客户端会执行 git send-pack,服务端会执行 git receive-pack
当在客户端执行 git pull/git fetch 时,客户端会执行 git fetch-pack,服务端会执行 git upload-pack。下面是 git push 的示例图,仅供参考:
sequenceDiagram participant client participant server autonumber Note over client: git push rect rgba(0, 255, 255, .10) client -->> + client: git send-pack end client ->> + server: send request rect rgba(0, 255, 255, .10) server -->> server: git receive-pack end server ->> client: neogotiate ok client ->> server: send data server ->> - client: donepre-receive#
特点:
- 无参数调用
- 标准输入传递引用信息
- 以非零值退出,所有的推送内容都不会被接受
用途:
- 钩子阻止对引用进行非快进(non-fast-forward)的更新
- 对该推送所修改的所有引用和文件进行访问控制

update#
特点:
- 受三个参数:引用的名字(分支),推送前的引用指向的内容的 SHA-1 值,以及用户准备推送的内容的 SHA-1 值
- 会为每一个准备更新的分支各运行一次
- 如果 update 脚本以非零值退出,只有相应的那一个引用会被拒绝;其余的依然会被更新
用途:
- 钩子阻止对引用进行非快进(non-fast-forward)的更新
- 对该推送所修改的所有引用和文件进行访问控制

post-receive#
特点:
- 无参数调用
- 标准输入传递引用信息
- 在整个过程完结以后运行
- 无法终止推送进程
- 客户端在它结束运行之前将保持连接状态
用途:
- 更新其他系统服务或者通知用户

实际推送时:


files-backend.c

不同阶段 GIT 使用的环境变量不同:

整个流程图见:https://www.processon.com/view/link/6075b4e8079129368880ce66
另外提一下 Git 的一些环境变量,这些环境变量在实际应用中比较有用:
环境变量#
GIT_TRACEfor general traces,GIT_TRACE_PACK_ACCESSfor tracing of packfile access,GIT_TRACE_PACKETfor packet-level tracing for network operations,GIT_TRACE_PERFORMANCEfor logging the performance data,GIT_TRACE_SETUPfor information about discovering the repository and environment it’s interacting with,GIT_MERGE_VERBOSITYfor debugging recursive merge strategy (values: 0-5),GIT_CURL_VERBOSEfor logging all curl messages (equivalent tocurl -v),GIT_TRACE_SHALLOWfor debugging fetching/cloning of shallow repositories.GIT_TRACE_BAREdon’t want: output
GIT_TRACE_PACKET 追踪 pack 包的信息
GIT_CURL_VERBOSE 对于 clone http:// 有用
GIT_TRACE_BARE 能够去除多余的信息
GIT_TRACE_REFS 追踪引用信息
GIT_LFS_SKIP_SMUDGE 跳过 LFS 文件的下载