再学 AI
第 34 课 / git-guardrails-claude-code
专项工具阅读 → 对照 → 问答 → 场景

通过工具前置钩子拦截特定 Git 命令

这份专项工具为 Claude Code 的 Bash 调用配置前置钩子,阻止列出的高影响 Git 操作。

还不清楚 Skill、Agent、安装和调用?先读 从零开始的6节入门课

在关系图中查看 git-guardrails-claude-code 与其他技能的关联 →

先把必要的概念讲清楚

这项技能用 Claude Code 工具调用前的钩子阻止一组 Git 命令。它让你看见自然语言规则如何转成运行时约束,也提醒你检查约束实际覆盖哪些入口。

下面是老师补充的入门说明;原作者的要求保留在中英对照正文中。所有例子均为帮助理解而构造的教学情境。

hook|事件发生时自动运行的钩子

在某个时点运行的脚本,例如 Git 提交前执行检查,或 Claude 使用命令工具前检查命令。它把规则变成可自动执行的动作。钩子覆盖什么取决于注册事件、匹配范围和运行环境,并不因安装一个脚本就控制所有工具。

CLI|命令行界面

通过输入文字命令操作程序,例如运行测试或检查 Git 状态。它与点按钮一样是操作入口,只是参数更容易记录、重复执行。读命令时先分清程序名、子命令、选项和目标路径;看懂命令不等于已执行它。

Git、commit、branch|版本与分支

Git 记录项目随时间的变化;commit 是一次有标识的修改记录;branch 是一条可继续发展的工作线。你可在功能分支试做收藏能力,验证后再合入主分支。保存了文件不等于已提交,提交了也不等于已推到服务器或已上线。

读原文,理解每一步为什么这样做

左右内容按小节对应;窄屏先中文、后英文。两种语言均完整展示,对应讲解紧接在小节之后。译文传达原文要求;老师讲解补充概念、原因、例子与适用边界。

中文译文English · 英文原文
中文译文
name: git-guardrails-claude-code
description: "配置 Claude Code 钩子,在执行前拦截危险 git 命令,如 push、reset --hard、clean、branch -D 等。用户希望阻止破坏性 Git 操作、添加安全钩子,或在 Claude Code 中阻止 push/reset 时使用。"
English · 英文原文
name: git-guardrails-claude-code
description: Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset in Claude Code.
中文译文

配置 Git 命令的执行前拦截

设置 PreToolUse 钩子,在 Claude 执行 Git 命令之前检查并拦截清单中的操作。

English · 英文原文

Setup Git Guardrails

Sets up a PreToolUse hook that intercepts and blocks dangerous git commands before Claude executes them.

中文译文

会拦截哪些操作

  • 所有形式的 git push,包括 --force
  • git reset --hard
  • git clean -fgit clean -fd
  • git branch -D
  • git checkout .git restore .

被拦截时,Claude 会收到消息,说明它没有执行该命令的权限。

English · 英文原文

What Gets Blocked

  • git push (all variants including --force)
  • git reset --hard
  • git clean -f / git clean -fd
  • git branch -D
  • git checkout . / git restore .

When blocked, Claude sees a message telling it that it does not have authority to access these commands.

老师讲解 · 对应上方原文 · 含教学举例

为什么这些命令被作者列入拦截范围

push 会把提交发送到远端;reset --hard、clean、强制删分支、恢复整个工作目录等操作可能丢弃本地工作。作者连普通 push 也拦截,是把共享写入决定留在更明确的控制点。

这不是说 Git push 天生恶意,而是该安全策略选择默认不让 Agent 直接使用。不同项目可能有不同已授权流程,应按需求定制。

原文列出的模式不是对所有潜在危险命令的完备枚举。检查脚本能识别什么、工具调用能否绕过,是实际保障程度的一部分。

文本规则、钩子和真正的权限是不同层次

技能文件说明如何设置;客户端在执行 Bash 前调用钩子;脚本再检查命令。这说明 Markdown 可以指导配置工作,但真正的拦截需要运行机制配合。

原文连普通 push 也拦截,是作者选择将远程推送纳入控制,并不是说每次普通推送都会破坏数据。清单表达的是该工具的限制范围。

验证示例把包含 git push origin main 的 JSON 输入交给脚本,观察拒绝结果,并不会真的执行推送。

它主要覆盖该客户端匹配到的 Bash 调用,不等于操作系统中所有 Git 行为都被禁止。项目级只约束当前项目配置,全局级影响该用户的其他项目。学习时应理解机制的实际覆盖范围,不把一份文本或匹配脚本当成无限的安全保证。

中文译文

配置步骤

English · 英文原文

Steps

中文译文
1. 确认生效范围

询问用户:只在当前项目生效,使用 .claude/settings.json;还是在所有项目生效,使用 ~/.claude/settings.json

English · 英文原文
1. Ask scope

Ask the user: install for this project only (.claude/settings.json) or all projects (~/.claude/settings.json)?

老师讲解 · 对应上方原文 · 含教学举例

项目范围与全局范围影响不同工作

项目设置只约束当前项目,全局设置会影响其他项目。把局部实验安装成全局规则,可能让原本已授权的其他流程突然失败。

复制脚本、设置可执行权限、在 settings 注册 PreToolUse 钩子,是三个不同动作。文件存在但没注册,就不会在事件发生时自动运行。

已有设置应合并而非覆盖,以免丢失其他钩子。你应该能看出本次增加了哪条规则、影响哪个范围。

中文译文
2. 复制附带脚本

脚本位于 scripts/block-dangerous-git.sh

项目级复制到 .claude/hooks/block-dangerous-git.sh;全局级复制到 ~/.claude/hooks/block-dangerous-git.sh。用 chmod +x 赋予执行权限。

English · 英文原文
2. Copy the hook script

The bundled script is at: scripts/block-dangerous-git.sh

Copy it to the target location based on scope:

  • Project: .claude/hooks/block-dangerous-git.sh
  • Global: ~/.claude/hooks/block-dangerous-git.sh

Make it executable with chmod +x.

中文译文
3. 加入设置文件

项目级 .claude/settings.json 使用:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-git.sh"
          }
        ]
      }
    ]
  }
}

全局级 ~/.claude/settings.json 使用:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/block-dangerous-git.sh"
          }
        ]
      }
    ]
  }
}

已有设置文件时,将钩子合并到现有 hooks.PreToolUse 数组,不覆盖其他设置。

English · 英文原文
3. Add hook to settings

Add to the appropriate settings file:

Project (.claude/settings.json):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-git.sh"
          }
        ]
      }
    ]
  }
}

Global (~/.claude/settings.json):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/block-dangerous-git.sh"
          }
        ]
      }
    ]
  }
}

If the settings file already exists, merge the hook into the existing hooks.PreToolUse array. Don't overwrite other settings.

中文译文
4. 询问是否自定义

问用户是否要增加或移除拦截模式,并据此修改复制后的脚本。

English · 英文原文
4. Ask about customization

Ask if user wants to add or remove any patterns from the blocked list. Edit the copied script accordingly.

中文译文
5. 验证拦截结果

运行:

echo '{"tool_input":{"command":"git push origin main"}}' | <path-to-script>

预期退出码为 2,并在标准错误输出打印 BLOCKED

English · 英文原文
5. Verify

Run a quick test:

echo '{"tool_input":{"command":"git push origin main"}}' | <path-to-script>

Should exit with code 2 and print a BLOCKED message to stderr.

老师讲解 · 对应上方原文 · 含教学举例

测试拦截器,不是执行真正的推送

示例把一段表示工具输入的 JSON 通过管道送进脚本,让脚本判断其中的命令。这测试的是它会不会拒绝 git push,不是让你实际向远端推送。

期待退出码 2 和拦截消息,是宿主识别拒绝的约定。只看到打印“BLOCKED”,但退出状态不正确,宿主未必真的停止操作。

自然语言“不要运行危险命令”和工具级拦截能相互补充。钩子不能替代仓库权限、备份或共享分支规则,也不自动适用于 Codex 的全部工具。

原作者:Matt Pocock · 中文翻译为非官方译本

来源:skills/misc/git-guardrails-claude-code/SKILL.md ↗

固定版本:3cca18b368ae95cdbdebbff572ccafa662551015

先作答,再看参考思路

Q1 · 理解

用自己的话说明:它解决什么问题,完成后会留下什么?

请各用一句话回答。若它只做规划或解释,不要把“已开发”“已部署”写成产物。

Q2 · 判断

有了钩子,是否就不需要平台权限和分支保护?

我已思考,查看参考思路

仍然需要按项目风险安排。钩子属于某一执行路径的控制,平台保护覆盖的是另一层,二者职责不同。

Q3 · 追问

原文中哪条要求在你的环境下可能不成立?

说出具体一句及其前提,例如工具不可用、资料缺失、已有项目约定冲突,或它只是作者偏好。把你的答案带回课堂,我们据此继续讨论。

课堂回传格式:第 34 课 / 我的理解 / Q2 回答 / 仍不理解的原句。这里是阅读教材;实时问答在我们的对话中进行。

把方法放进一个具体情境

教学案例:学习仓库暂时不允许推送,可以让对应钩子拒绝 git push。但如果另一个客户端没有此钩子,不能假设它也受到保护。

边界与容易误读的地方

Claude 配置不能直接视作其他 Agent 的配置。拦截正常 push 也可能阻塞已经授权的发布,因此应清楚其范围与解除流程。

讨论后再实践:先判断上述情境是否适用,再选择真实任务。现在无需安装、运行命令或修改现有项目。

关联阅读