从仓库中移除敏感信息

1,020 阅读6分钟
原文链接: mp.weixin.qq.com

如果你将敏感数据(如密码或 SSH 密钥)提交到 Git 仓库,你能够将其从历史记录中删除。 要从仓库的历史记录中完全删除不需要的文件,你可以使用 git filter-branch命令或 BFG Repo-Cleaner。

git filter-branch 命令和 BFG Repo-Cleaner 会重写你的版本库的历史记录,这会更改你修改的现有提交和任何相关提交的SHA。更改的提交SHA可能会影响仓库中的打开请求。我们建议在从仓库中删除文件之前合并或关闭所有打开的请求。

你可以使用 git rm 从最新的提交中删除文件。 有关删除使用最新提交添加的文件的信息,请参阅“从仓库历史记录中删除文件”

警告:一旦你推送了一个提交到 GitHub,你应该考虑它包含的任何数据都会被泄露。如果你提交了密码,请更改密码!如果你提交了密钥,请生成一个新密钥。

本文将告诉你如何使用 GitHub 仓库中的任何分支或标签无法访问敏感数据。然而,重要的是要注意到这些提交可能仍然可以在你的存储库的任何克隆或分支中直接通过它们在 GitHub上 的缓存视图中的 SHA-1 哈希以及通过引用它们的任何拉取请求来访问。你无法对仓库中的现有克隆或分支做任何事情,但可以通过联系 GitHub 支持,永久删除所有存储库的缓存视图并在GitHub上提出请求。

从仓库历史中清除文件

使用 BFG

BFG Repo-Cleaner 和 git filter-branch 类似,用于删除不需要的文件,是一种更快速、更简单的替代方法。 例如,要删除含有敏感数据的文件并保持最新提交不变,运行:

bfg--delete-files YOUR-FILE-WITH-SENSITIVE-DATA

要替换 passwords.txt中 列出的所有文本,可以在仓库历史记录中找到它,运行:

bfg--replace-text passwords.txt

有关完整的使用和下载说明,请参阅BFG Repo-Cleaner的文档。

使用 filter-branch

警告:如果你在暂存(stash)更改后运行 git filter-branch,你将无法使用其他暂存命令检索你的更改。 在运行 git filter-branch 之前,我们建议不要修改你所做的任何更改。要取消最后一组隐藏的更改,请运行 git stash show-p|git apply-R。 有关更多信息,请参阅Git Tools Stashing。

为了说明 git filter-branch 如何工作,我们将向你展示如何从仓库的历史记录中删除具有敏感数据的文件,并将其添加到 .gitignore 中以确保它不会被意外重新提交。

1. 如果你的历史记录中尚未拥有敏感数据的存储库本地副本,请将克隆仓库到本地 电脑。

  1. git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY

  2. Initialized empty Git repository in /Users/YOUR-FILE-PATH/YOUR-REPOSITORY/.git/

  3. remote: Counting objects: 1301, done.

  4. remote: Compressing objects: 100% (769/769), done.

  5. remote: Total 1301 (delta 724), reused 910 (delta 522)

  6. Receiving objects: 100% (1301/1301), 164.39 KiB, done.

  7. Resolving deltas: 100% (724/724), done.

2. 切换到仓库的工作目录。

  1. cd YOUR-REPOSITORY

3. 运行以下命令,用要删除的文件的路径替换 PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA,而不仅仅是文件名。 这些参数:

  • 强制 Git 处理但不检出每个分支和标签的整个历史记录

  • 移除指定的文件以及作为结果生成的任何空提交

  • 重写你现有的标签

  1. git filter-branch --force --index-filter \

  2. 'git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA' \

  3. --prune-empty --tag-name-filter cat -- --all

  4. Rewrite 48dc599c80e20527ed902928085e7861e6b3cbe6 (266/266)

  5. Ref 'refs/heads/master' was rewritten

注意:如果包含敏感数据的文件曾经存在于任何其他路径(因为它已被移动或重命名),那么你也必须在这些路径上运行此命令。

4. 将含有敏感数据的文件添加到 .gitignore中,以确保你不会意外地再次提交。

  1. echo "YOUR-FILE-WITH-SENSITIVE-DATA" >> .gitignore

  2. git add .gitignore

  3. git commit -m "Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore"

  4. [master 051452f] Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore

  5. 1 files changed, 1 insertions(+), 0 deletions(-)

5. 仔细检查你是否已经从仓库的历史记录中删除了你想要的所有内容,并检查了所有分支。

6. 一旦对仓库的状态感到满意,强制推送本地更改以覆盖你的 GitHub 仓库以及你推送的所有分支:

  1. git push origin --force --all

  2. Counting objects: 1074, done.

  3. Delta compression using 2 threads.

  4. Compressing objects: 100% (677/677), done.

  5. Writing objects: 100% (1058/1058), 148.85 KiB, done.

  6. Total 1058 (delta 590), reused 602 (delta 378)

  7. To https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git

  8. + 48dc599...051452f master -> master (forced update)

7. 为了从标签发布中删除敏感文件,你还需要强制推送您的 Git 标签:

  1. git push origin --force --tags

  2. Counting objects: 321, done.

  3. Delta compression using up to 8 threads.

  4. Compressing objects: 100% (166/166), done.

  5. Writing objects: 100% (321/321), 331.74 KiB | 0 bytes/s, done.

  6. Total 321 (delta 124), reused 269 (delta 108)

  7. To https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git

  8. + 48dc599...051452f master -> master (forced update)

8. 告诉你的同事 rebase 而不是 merge 它们创建的任何分支,这些分支是从旧的(受污染的)存储库历史中创建的。一次合并提交可能会重新引入一些或所有你刚才去除清除问题的受污染历史记录。

经过一段时间,你确信 git filter-branch 没有意外的副作用,你可以强制你的本地仓库中的所有对象被解除引用和垃圾收集,使用下面的命令(使用Git 1.8.5或更新的版本):

  1. git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin

  2. git reflog expire --expire=now --all

  3. git gc --prune=now

  4. Counting objects: 2437, done.

  5. Delta compression using up to 4 threads.

  6. Compressing objects: 100% (1378/1378), done.

  7. Writing objects: 100% (2437/2437), done.

  8. Total 2437 (delta 1461), reused 1802 (delta 1048)

注意:你也可以通过将已过滤的历史记录推送到新的或空的仓库,然后从GitHub创建新的克隆来实现此目的。

在未来避免意外的提交

有几个简单的技巧可以避免提交你不想提交的东西:

  • 使用 GitHub Desktop 或 gitk 等可视程序来提交更改。 可视化程序通常可以更容易地看到每个提交将会添加,删除和修改哪些文件。

  • 避免在命令行中使用 git add. 和  git commit-a 这样的 catch-all 命令 - 改为使用 git add filename和  git rm filename 来单独分级文件。

  • 使用 git add--interactive 在每个文件中分别查看和分级更改。

  • 使用 git diff--cached 来查看你为提交而进行的更改。 只要你不使用 -a 标志,  git commit 就会产生确切的差异。

以上。

欢迎搜索微信号 mad_coder 或者扫描二维码关注公众号: