name: git-guardrails-claude-code description: "配置 Claude Code 钩子,在执行前拦截危险 git 命令,如 push、reset --hard、clean、branch -D 等。用户希望阻止破坏性 Git 操作、添加安全钩子,或在 Claude Code 中阻止 push/reset 时使用。"
通过工具前置钩子拦截特定 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 是一条可继续发展的工作线。你可在功能分支试做收藏能力,验证后再合入主分支。保存了文件不等于已提交,提交了也不等于已推到服务器或已上线。
读原文,理解每一步为什么这样做
左右内容按小节对应;窄屏先中文、后英文。两种语言均完整展示,对应讲解紧接在小节之后。译文传达原文要求;老师讲解补充概念、原因、例子与适用边界。
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 命令之前检查并拦截清单中的操作。
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 -f和git clean -fd。git branch -D。git checkout .和git restore .。
被拦截时,Claude 会收到消息,说明它没有执行该命令的权限。
What Gets Blocked
git push(all variants including--force)git reset --hardgit clean -f/git clean -fdgit branch -Dgit 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 行为都被禁止。项目级只约束当前项目配置,全局级影响该用户的其他项目。学习时应理解机制的实际覆盖范围,不把一份文本或匹配脚本当成无限的安全保证。
配置步骤
Steps
1. 确认生效范围
询问用户:只在当前项目生效,使用 .claude/settings.json;还是在所有项目生效,使用 ~/.claude/settings.json?
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 赋予执行权限。
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 数组,不覆盖其他设置。
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. 询问是否自定义
问用户是否要增加或移除拦截模式,并据此修改复制后的脚本。
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。
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 的全部工具。
先作答,再看参考思路
用自己的话说明:它解决什么问题,完成后会留下什么?
请各用一句话回答。若它只做规划或解释,不要把“已开发”“已部署”写成产物。
有了钩子,是否就不需要平台权限和分支保护?
我已思考,查看参考思路
仍然需要按项目风险安排。钩子属于某一执行路径的控制,平台保护覆盖的是另一层,二者职责不同。
原文中哪条要求在你的环境下可能不成立?
说出具体一句及其前提,例如工具不可用、资料缺失、已有项目约定冲突,或它只是作者偏好。把你的答案带回课堂,我们据此继续讨论。
把方法放进一个具体情境
教学案例:学习仓库暂时不允许推送,可以让对应钩子拒绝 git push。但如果另一个客户端没有此钩子,不能假设它也受到保护。
边界与容易误读的地方
Claude 配置不能直接视作其他 Agent 的配置。拦截正常 push 也可能阻塞已经授权的发布,因此应清楚其范围与解除流程。
讨论后再实践:先判断上述情境是否适用,再选择真实任务。现在无需安装、运行命令或修改现有项目。