bash - 了解为什么 git-filter-branch 没有清理我的历史记录
问题描述
我使用 gitleaks 检查我的回购历史中泄露的秘密。当我运行以下命令并强制推送时
git filter-branch --force --index-filter \
'git rm -r --cached --ignore-unmatch terra/fixtures.go' \
--prune-empty --tag-name-filter cat -- --all
它似乎工作,除了我注意到以下几点:
WARNING: Ref 'refs/heads/automate_tests' is unchanged
WARNING: Ref 'refs/heads/ethRawTransaction' is unchanged
WARNING: Ref 'refs/heads/feature/177/leave-bastion' is unchanged
WARNING: Ref 'refs/heads/feature/FAQ' is unchanged
WARNING: Ref 'refs/heads/master' is unchanged
WARNING: Ref 'refs/heads/mjolnir' is unchanged
WARNING: Ref 'refs/heads/tmp' is unchanged
WARNING: Ref 'refs/remotes/origin/master' is unchanged
WARNING: Ref 'refs/remotes/origin/automate_tests' is unchanged
WARNING: Ref 'refs/remotes/origin/bug/0.0.11-beta-fix' is unchanged
WARNING: Ref 'refs/remotes/origin/bug/bastion-ssh' is unchanged
WARNING: Ref 'refs/remotes/origin/bug/fix-examples-merge' is unchanged
WARNING: Ref 'refs/remotes/origin/develop' is unchanged
WARNING: Ref 'refs/remotes/origin/ethRawTransaction' is unchanged
WARNING: Ref 'refs/remotes/origin/feature/168/auto-ssh-to-bastion' is unchanged
WARNING: Ref 'refs/remotes/origin/feature/169/ethstats_for_pantheon' is unchanged
WARNING: Ref 'refs/remotes/origin/feature/175/ssh-to-certain-nodes' is unchanged
WARNING: Ref 'refs/remotes/origin/feature/176/tagging-nodes-to-ips' is unchanged
WARNING: Ref 'refs/remotes/origin/feature/177/leave-bastion' is unchanged
WARNING: Ref 'refs/remotes/origin/feature/FAQ' is unchanged
WARNING: Ref 'refs/remotes/origin/feature/README' is unchanged
WARNING: Ref 'refs/remotes/origin/master' is unchanged
WARNING: Ref 'refs/remotes/origin/mjolnir' is unchanged
WARNING: Ref 'refs/remotes/origin/tmp' is unchanged
WARNING: Ref 'refs/tags/0.0.4' is unchanged
WARNING: Ref 'refs/tags/20190820141131-866368a' is unchanged
WARNING: Ref 'refs/tags/20190820142202-bd96767' is unchanged
WARNING: Ref 'refs/tags/20190820143451-fc7f46a' is unchanged
WARNING: Ref 'refs/tags/20190820143903-832818a' is unchanged
WARNING: Ref 'refs/tags/20190820150546-05e3105' is unchanged
WARNING: Ref 'refs/tags/20190820154631-da0cdab' is unchanged
WARNING: Ref 'refs/tags/20190820160956-047caa6' is unchanged
WARNING: Ref 'refs/tags/20190820162243-a300fa5' is unchanged
WARNING: Ref 'refs/tags/20190820170410-47f8878' is unchanged
WARNING: Ref 'refs/tags/untagged-f148f02c4d71ed0bea99' is unchanged
WARNING: Ref 'refs/tags/v.0.0.1' is unchanged
WARNING: Ref 'refs/tags/v0.0.1' is unchanged
WARNING: Ref 'refs/tags/v0.0.1-alpha' is unchanged
WARNING: Ref 'refs/tags/v0.0.10' is unchanged
WARNING: Ref 'refs/tags/v0.0.11-beta' is unchanged
WARNING: Ref 'refs/tags/v0.0.14' is unchanged
WARNING: Ref 'refs/tags/v0.0.3-alpha' is unchanged
WARNING: Ref 'refs/tags/v0.0.4-chaos-poc' is unchanged
结果,泄漏的数量似乎并没有下降。
我对为什么会发生这种情况感到困惑,并希望得到任何指示。
解决方案
报告为未更改的 refs在其历史记录中git filter-branch
没有任何名称的文件。terra/fixtures.go
Filter-branch 通知您,尽管您要求它更新这些分支名称以指向任何复制的提交,但在此过程中实际上没有复制任何提交。
找到具有此类文件的可访问提交哈希 ID 列表,然后在此类哈希 ID 上运行可能会很有趣git branch --contains
。见下文。
哪些提交包含文件F?
请注意,这是对不同问题的不同答案。它也不是寻找修改了某些路径名的提交,而是寻找根本存在某些路径名的提交。
我们首先使用git rev-list
列出所有提交:
git rev-list --all |
的输出git rev-list
只是一个列表,列出了可以从命名修订版访问的每个提交哈希 ID。在这种情况下,--all
命名所有分支和标签,以及其他 refs,例如refs/stash
,但不是任何 reflog 条目。
然后,对于列出的每个提交,我们要测试此提交是否包含命名文件。此时您通常需要很多可编程性。例如,假设文件名为a/b/c.txt
. 你也想找A/B/C.TXT
吗?如果您使用的是 Windows 或 MacOS,则可能。如果你在 Linux 上,可能不会。或者,也许您想查找名称以某种模式开头或结尾的任何文件。
我们在这里要做的是 use git ls-tree -r
,它列出所有文件名,然后通过搜索和状态命令运行它们,例如grep
. 请注意,grep
搜索正则表达式,而不是 glob 模式,因此a*b
意味着零个或多个a
字符后跟一个b
字符,并将匹配字符串“abc.txt”、“b”、“flobby”等:这些都有零个或多个a
s 后跟一个b
. 我们将让实际匹配的名称显示出来,以便人们可以在需要时应用进一步的过滤:
git rev-list --all |
while read hash; do
git ls-tree -r $hash > /tmp/files
if grep -s 'terra/fixtures\.go' /tmp/files; then
echo "commit ${hash} :"
grep 'terra/fixtures\.go' /tmp/files
fi
done
rm /tmp/files
这组命令的输出——你可能应该把它放在一个文件中,我没有测试过,可能包含错误——是一个适合提取的提交哈希 ID 列表,但后面跟着匹配的名称:你可能应该丢弃匹配,例如,sputerra/fixtures.gobble
。
(可以编写grep
更精确的匹配模式。在这种情况下,用and锚定正则表达式就足够了。在更复杂的情况下,需要更复杂的正则表达式。我把这个留给使用代码的人。)^
$
获得哈希 ID——运行上面的代码并重定向到一个文件,清理文件,然后提取更有趣的哈希 ID——然后你可以这样做:
git branch --contains <hash>
在任何给定的提交哈希上查看哪些分支包含该特定提交。请注意,可能有零个或多个分支包含任何给定的提交。有关(更多)关于此的信息,请阅读并理解Think Like (a) Git。
推荐阅读
- regex - 匹配以开头和结尾的单词
- matlab - 如何创建在后台播放白噪声的 Psychtoolbox 声音时间表?
- docker - Docker 不绑定端口
- image - Amcharts4:如何将图像添加到轴(valueAxis)标签?
- ajax - Laravel:使用 Ajax 更新数据库。接下来我该怎么办?
- android - 从 Firebase 读取数据并更新 TextView
- java - AWS S3:我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法
- mysql - 如何从我的填充查询中排除第一次出现在后续行中的值的每一行
- c++ - 在 C++ 中使用 itoa() 函数将整数转换为字符串的时间复杂度?
- php - .htaccess - 重定向除一个以外的所有 URL