当敏感信息(如密码、密钥、私人域名等)被提交到 Git 仓库后,即使后续提交中删除了这些内容,它们仍然存在于 Git 历史记录中。本文介绍如何彻底清除这些敏感数据。
问题场景
- 不小心提交了 API 密钥、密码
- 配置文件中包含真实域名或个人信息
- 已推送到 GitHub 等公开仓库
解决方案’"
方法一:使用 git filter-branch(内置工具)
适用于替换历史中所有提交的某个文件内容。
# 1. 暂存当前未提交的更改
git stash'"
# 2. 替换历史中所有 README.md 文件里的敏感内容
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --force --tree-filter \
"find . -name 'README.md' -exec sed -i '' 's/敏感内容/替换内容/g' {} \;" \
-- --all
# 3. 恢复暂存的更改
git stash pop
# 4. 强制推送到远程仓库(覆盖历史)
git push origin main --force
参数说明
| 参数 | 说明 |
|---|---|
| <code>–force</code> | 强制执行,即使已有备份 |
| <code>–tree-filter</code> | 对每个提交的文件树执行命令 |
| <code>– –all</code> | 处理所有分支 |
| <code>sed -i ''</code> | macOS 下的原地替换(Linux 用 <code>sed -i</code>) |
方法二:使用 BFG Repo-Cleaner(推荐,更快)
适用于删除大文件或敏感文件。
# 安装 BFG
brew install bfg
# 删除某个文件的所有历史
bfg --delete-files 敏感文件.txt
# 或替换敏感文本
bfg --replace-text passwords.txt
# 清理并强制推送
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push origin main --force
方法三:使用 git filter-repo(官方推荐)
# 安装
brew install git-filter-repo
# 替换敏感内容
git filter-repo --replace-text <(echo '敏感内容==>替换内容')
# 重新添加远程并推送
git remote add origin https://github.com/user/repo.git
git push origin main --force
注意事项
- 强制推送有风险:会覆盖远程历史,协作者需要重新克隆仓库
- 轮换密钥:敏感信息一旦泄露,应立即轮换(如重新生成 API Key)
- GitHub 缓存:GitHub 可能会缓存提交,联系 GitHub 支持可请求清除
- 本地备份:操作前建议备份仓库 <code>cp -r .git .git.backup</code>
预防措施
- 使用 <code>.gitignore</code> 忽略敏感文件
- 使用环境变量存储敏感配置
- 提交前检查 <code>git diff –staged</code>
- 启用 GitHub 的 Secret Scanning 功能
总结
- git stash – 暂存当前未提交的更改
- git filter-branch –tree-filter – 遍历所有历史提交,用 sed 替换敏感内容
- git stash pop – 恢复暂存的更改
- git push –force – 强制推送覆盖远程历史