.gitignore仅对未跟踪文件生效,已跟踪的.env等需git rm --cached;git diff配合grep可精准定位密钥变更;pre-commit钩子是强制拦截最后一道防线,缺一不可。

直接在提交前拦截敏感信息,靠的是 .gitignore + git diff + 预提交钩子三层防线,缺一不可。只配 .gitignore 无法阻止已被 Git 跟踪的文件;只看 VSCode 界面差异容易漏掉二进制或大文件里的密钥;不加钩子就等于把审查权交给开发者“自觉”。
为什么 .gitignore 经常失效?
常见错误是以为加了规则就万事大吉——其实 .gitignore 只对“未被跟踪”的文件生效。如果 .env 已经被 git add 过,后续再往 .gitignore 里加 .env,Git 仍会继续追踪它。
- 检查文件是否已被跟踪:
git ls-files --cached .env,有输出即表示已跟踪 - 取消已跟踪的敏感文件:
git rm --cached .env(保留本地文件) - 全局忽略 VSCode 配置:
git config --global core.excludesfile ~/.gitignore_global,然后在该文件中写入.vscode/ - 注意路径写法:
.env忽略项目根目录下的文件,**/.env才能匹配子目录
如何用 git diff 快速定位敏感变更?
VSCode 的图形化 Diff 看起来直观,但默认只显示文本行级差异,对硬编码密钥、base64 token 或 JSON 中嵌套字段极易误判。命令行 git diff 配合过滤更可靠。
- 只看未暂存的敏感文件变更:
git diff .env .env.local config.json - 高亮可能含密钥的行:
git diff | grep -E "(API_KEY|password|secret|token|PRIVATE KEY)" - 对比暂存区内容(防止
git add后忘记检查):git diff --cached - 避免空白干扰:
git diff -b忽略空格变化,聚焦实质内容
pre-commit 钩子才是最后一道保险
人总会疏忽,而机器不会。仅靠提醒或文档约束,无法杜绝误提交。必须让提交动作本身在检测失败时自动中断。
- 安装
git-secrets:brew install git-secrets(macOS)或从 GitHub 下载二进制 - 初始化钩子:
git secrets --install,它会在.git/hooks/pre-commit写入检测逻辑 - 添加 AWS/GitHub/Slack 密钥模式:
git secrets --register-aws - 自定义规则防硬编码:
git secrets --add 'PASSWORD\s*=\s*["''].*["'']' - 注意:钩子只对当前仓库生效,团队需统一初始化,或改用
husky+lint-staged方案
最容易被忽略的是“已跟踪文件”的状态迁移——比如某天你 git add config.json 测试配置,之后忘了删,又加了 .gitignore 规则,它依然会提交。每次新增敏感文件类型,都要同步执行 git rm --cached + 提交 .gitignore 更新 + 检查钩子是否覆盖新类型。











