本文目录导读:

Git 钩子脚本可以用来在本地提交代码前检查代码中是否遗漏了待办事项(TODO)、调试注释或未完成的修改,从而确保“反馈闭环”(即:问题被记录、修复、验证、关闭)没有被打破。
以下是几种常见的 Git 钩子检查反馈闭环的方法和示例脚本。
核心思路
反馈闭环的检查,本质上是禁止某些特定模式的文本进入代码仓库,常见的“断环”情况包括:
- 遗留的
TODO/FIXME/HACK注释(如果没有对应的 Issue 或任务跟踪)。 - 调试代码(如
console.log、print、var_dump、@test标记等)。 - 被注释掉的代码块(表明未清理的遗留逻辑)。
- 未解决的合并冲突标记(
<<<<<<<、、>>>>>>>)。
常用钩子位置
pre-commit:最常用,在用户输入git commit后、生成提交对象前触发,可以检查暂存区(staged)的代码。commit-msg:用于检查提交信息是否符合规范(如是否包含 Issue 编号),从而确保提交和任务系统关联。pre-push:在git push时触发,检查更严格,防止问题流到远程仓库。
脚本示例:检查暂存区代码(pre-commit 钩子)
这个脚本会检查即将提交的代码中是否包含“断环”模式,如果发现,则阻止提交。
文件位置: .git/hooks/pre-commit(需要赋予执行权限:chmod +x .git/hooks/pre-commit)
#!/bin/bash
# pre-commit 钩子:检查反馈闭环
# 作用:阻止包含 TODO、FIXME、调试注释或合并冲突标记的代码提交
echo "🔍 正在检查反馈闭环完整性..."
# 设置错误标志
error=0
# 1. 检查合并冲突标记(最严重的断环)
if git diff --cached --diff-filter=ACM | grep -E '^\+.*<<<<<<<|^\+.*=======|^\+.*>>>>>>>' > /dev/null 2>&1; then
echo "❌ 错误:暂存区中存在未解决的合并冲突标记(<<<<<<< / ======= / >>>>>>>)"
echo " 请解决冲突后再提交。"
error=1
fi
# 2. 检查 TODO / FIXME / HACK 注释(根据团队策略决定是否禁止)
# 有些团队允许 TODO 但要求附带 Issue 编号,此处简单禁止所有 TODO/FIXME
if git diff --cached --diff-filter=ACM | grep -E '^\+.*\b(TODO|FIXME|HACK|XXX)\b' > /dev/null 2>&1; then
echo "❌ 错误:暂存区中包含未完成的标记:"
git diff --cached --diff-filter=ACM | grep -E '^\+.*\b(TODO|FIXME|HACK|XXX)\b' | sed 's/^\+//'
echo " 请移除或处理这些标记后再提交,如果需要遗留,请附加 Issue 编号并修改钩子规则。"
error=1
fi
# 3. 检查调试代码(如 console.log, print, var_dump 等)
# 仅检查常见调试关键字,避免误伤(如正常的 "print" 字符串)
if git diff --cached --diff-filter=ACM | grep -E '^\+.*\b(console\.log|console\.debug|var_dump|dd\(|print_r|pry\b|binding\.pry|debugger)\b' > /dev/null 2>&1; then
echo "❌ 错误:暂存区中疑似包含调试代码 (console.log, var_dump, debugger 等)"
echo " 请移除调试语句后重新提交。"
error=1
fi
# 4. 检查被注释掉的代码块(超过3行的连续注释代码)
# 这个检查比较复杂,这里提供一个简单的版本:检测注释中出现的代码关键字
if git diff --cached --diff-filter=ACM | grep -E '^\+.*//\s*(if|for|while|function|def|class|import|require|const|let|var)\b' > /dev/null 2>&1; then
echo "⚠️ 警告:暂存区中存在被注释掉的代码(疑似遗留代码)"
echo " 建议清理后提交,或确认这是必要的注释。"
# 这里设为 error=1 会阻止提交,可根据团队策略调整为只警告
# error=1
fi
# 汇总结果
if [ $error -ne 0 ]; then
echo "❌ 反馈闭环检查未通过,提交被阻止。"
echo " 请修复上述问题后再执行 git commit。"
exit 1
else
echo "✅ 反馈闭环检查通过,提交继续。"
exit 0
fi
更高级的策略:允许 TODO 但要求关联 Issue
有些团队允许遗留 TODO,但要求必须关联一个 Issue 编号,以便追踪闭环。
示例(修改上述脚本的 TODO 检查部分):
# 允许 TODO 但要求格式为 TODO(#123) 或 TODO(ISSUE-123)
if git diff --cached --diff-filter=ACM | grep -E '^\+.*\bTODO\b(?!\s*\()' > /dev/null 2>&1; then
echo "❌ 错误:TODO 注释必须附带 Issue 编号,格式:TODO(#123) 或 TODO(ISSUE-123)"
error=1
fi
如何在项目中统一管理这些钩子?
手动复制 .git/hooks/ 文件容易被覆盖,也不便于团队共享,推荐以下方式:
-
使用工具管理:
- Husky(Node.js 项目常用):可以在
package.json中配置钩子,并自动安装到每个开发者的.git/hooks/。 - pre-commit(Python 项目常用):一个框架,可以在
.pre-commit-config.yaml中声明检查规则(包括社区已有的检查器)。
- Husky(Node.js 项目常用):可以在
-
将钩子脚本放在项目目录中(如
scripts/git-hooks/),然后通过Makefile或构建脚本让开发者运行make install-hooks来建立符号链接。
注意事项
- 性能:钩子脚本会影响每次提交的速度,避免在钩子中运行耗时的操作(如完整测试套件)。
- 误报处理:
grep模式可能误伤正常代码(如变量名debug_mode或注释中的描述),需要设计合理的正则表达式,并允许开发者通过--no-verify临时绕过(但要提醒他们谨慎使用)。 - 团队策略:检查规则需要团队达成一致并文档化,过于严格的检查会降低效率,过于宽松则失去意义。
通过合理配置 pre-commit 钩子,可以确保代码中不遗留未完成的调试代码或未关联 Issue 的 TODO,从而维护“反馈闭环”的完整性。