Git钩子需重命名去.sample后缀并chmod+x赋权;首行用#!/usr/bin/env bash;pre-commit检代码、commit-msg检提交信息;post-receive部署需指定--work-tree;团队应使用husky或pre-commit工具统一管理。

怎么让 Git 钩子真正跑起来?
Git 钩子不会自动生效——哪怕你把脚本放进 .git/hooks,它也大概率静默失败。核心就两点:文件名必须准确、权限必须可执行。
-
.git/hooks下的钩子文件不能带.sample后缀(比如pre-commit.sample要重命名为pre-commit) - 必须用
chmod +x pre-commit赋予可执行权限;Windows 用户若用 Git Bash,也得执行这步,别信“Windows 不需要” - 钩子脚本第一行必须是有效的 shebang,推荐统一用
#!/usr/bin/env bash,它比#!/bin/bash更跨平台(尤其在 macOS 或某些 Linux 发行版上) - 别直接编辑
.git/hooks里的文件来“共享钩子”——它不进版本控制,团队协作时会丢,后面会说替代方案
pre-commit 和 commit-msg 哪个更适合校验提交内容?
pre-commit 检代码,commit-msg 检文字,分工明确,混用反而容易出错。
CNB 云原生构建平台的 Git 操作技能,支持代码克隆、提交、推送、分支管理、Merge Request 管理、流水线触发与结果读取。初次使用需收集用户的 Git 用户名和邮箱。
-
pre-commit在git commit写入对象前触发,能读取暂存区(git diff --cached),适合做代码格式检查(Prettier)、敏感信息扫描(如密码、密钥硬编码)、类型检查(tsc --noEmit) -
commit-msg接收一个参数:$1,即 commit message 文件路径;适合强制规范格式(如要求以feat:/fix:开头)、拒绝空消息、或自动补前缀(echo "WIP: $(cat $1)" > $1) - 注意:
pre-commit里改不了 commit message;想动态注入内容(比如 Jira ID),得用prepare-commit-msg,它会在编辑器打开前修改 message 文件
post-receive 部署脚本为什么总在远程仓库失败?
因为 post-receive 只存在于远程仓库的 .git 目录里,且它运行在 bare 仓库中——没有工作目录,git checkout 会报错 fatal: this operation must be run in a work tree。
- 正确做法是用
git --work-tree=/path/to/deploy-dir --git-dir=/path/to/repo.git checkout -f refs/heads/main - 务必检查
user.deploy-dir这类自定义配置是否已设置:git config --get user.deploy-dir,没设就提前 exit,别让脚本卡住 - 分支判断别写死
master,用正则匹配更稳:[[ "$refspec" =~ ^(main|master|prod.*|release/.*$) ]] - 输出到
stderr的内容(echo "xxx" >&2)才能被 push 客户端看到;stdout 默认被吞掉
怎么让钩子在团队里可靠又不扯皮?
手动复制 .git/hooks 是最不可靠的方式——没人记得同步,CI 环境根本没它,新成员第一天就踩坑。
- 用
husky(Node.js 项目)或pre-commit(Python/通用)这类工具管理钩子:它们把钩子逻辑写进package.json或.pre-commit-config.yaml,随代码一起版本化 - 避免在钩子里调用全局命令(如
python、node)——不同机器版本可能不一致;优先用项目本地二进制(./node_modules/.bin/eslint) - 钩子执行时间别超过 3 秒,否则开发者会下意识
git commit --no-verify绕过,等于白写;耗时操作(如全量测试)应挪到 CI
.git 目录可写、比如网络通畅。先验证这些,再写逻辑。

















