首页 > 解决方案 > 从 git 历史记录中删除垃圾邮件

问题描述

我已经“继承”了一个肮脏的 git 存储库,其中包含大约 5k 有效提交和大约 50k 垃圾邮件提交(这是曾经是世界可写 wiki 的编辑历史)。我们正在迁移格式,所以这是改写历史的好时机。我不想完全放弃历史,但无论是提交量还是原始内容量,垃圾邮件都是压倒性的。回滚到最后一个好的提交的旧适度技术留下了很多垃圾。

我可以找到大约 80% 的错误提交,并且使用起来没有太多麻烦,git log -S并且可以使用一些正则表达式。大多数垃圾邮件内容非常明显。问题是我不确定如何处理我想要删除的大量提交列表。

注意我非常熟悉git并且每小时使用一次(除了git revise已经接管了很多负载git rebase之外,这本来应该是分钟的),我知道如何手动完成这项工作,但我需要一个自动化的解决方案。通常我会转向,但我不确定要使用什么工具来检查当前差异。git filter-branch

我曾想过编写一个脚本来操作一个变基脚本,但我认为这会让我遇到误报的麻烦。我可能可以捕获并丢弃原始的破坏和回滚,但是当我错过了该等式的一侧时会发生什么?我希望可能匹配的REST在其中一个没有干净地变基时成功而不失败。

注意我不想根据我的匹配操作文件的内容或添加/删除文件,我想检查补丁的内容并根据它决定选择或删除。

什么是最好的git工具?

标签: gitrebasespamgit-filter-branch

解决方案


一种可能性是使用 Git 的移植文件或git replace. 首先,识别所有“好的”提交,即非垃圾邮件提交,还包括“清理/恢复”提交。例如,通过提交者电子邮件或类似机制(您提到 pickaxe/ -S)过滤您的历史记录。

一旦你有了“好”提交的列表,使用paste命令进行简单的转换就可以得到移植文件的内容,即:

commit parent1 parent2 parent3...

说,您的良好提交如下(最新的提交在顶部):

b3fb1155cd5352da674d93ce4b0a1567674f6d27
b460ef0aea564e587e5866107c0fc52adf552ca1
9f803dd18c89e13f47170e1ace1d0abb992cfeee

那么您需要在您的移植文件中包含以下内容:

b3fb1155cd5352da674d93ce4b0a1567674f6d27 b460ef0aea564e587e5866107c0fc52adf552ca1
b460ef0aea564e587e5866107c0fc52adf552ca1 9f803dd18c89e13f47170e1ace1d0abb992cfeee

这很容易通过以下方式获得:

sed 1d commits | paste commits - | sed '$d'

将此文件移动到并使用或.git/info/grafts验证生成的历史记录。如果您对结果感到满意,请使用重写历史并保存您的移植文件。然后,您可以删除.git loggitkgit filter-branch.git/info/grafts

请参阅https://stackoverflow.com/a/3811217/112968了解如何使用非弃用替换机制。在这种情况下使用移植文件更容易解释(它仍然适用于当前的 Git 版本,所以为什么不使用它?:))


推荐阅读