TL; DR:我们的git存储库中有一个短语必须从历史中删除,而不仅仅是分支的头部。除了从开发和创建新存储库的头部中删除它之外还有哪些其他方法?我们希望保持尽可能多的历史。
出于icky法律原因,我和我的团队必须从我们的代码库中删除所有单词的实例(我们称之为Voldemort只是为了娱乐和相关性)。令人讨厌的是,我们不仅要从分支机构的提示中删除Voldemort,我们必须将其从我们的存储库中的每次提交中删除(该诉讼是 >“没有开发人员能够合理地恢复到伏地魔在代码中的状态”。
我们不再使用Voldemort,但代码中有一些地方仍然提到像评论一样。 (是的,作为法律诉讼的一部分,我们必须从我们的代码中删除侵权评论。)
最初的计划是清除不得提及的单词,然后创建一个新的存储库并将当前状态作为初始提交。我们不想失去我们所有的历史 1 !所以我们想知道是否有办法避免这种情况。
所以,问题是我们如何在尽可能多地保留历史 1 的同时从历史中删除Voldemort这个不可提及的词?另外,我们可以做些什么来确保它不在任何提交中?我们想知道如何检查我们的工作以确保它已经消失。
1:根据历史记录,我并不是指具体的提交,我只是想查看文件的历史记录,知道是谁做了什么,如果历史记录是对我没关系在git意义上的“重写历史”中,我实际上猜测它是唯一的方法。
似乎我们想要做git log --patch | grep 'Voldemort'
之类的事情来查找添加Voldemort的提交,然后对编辑提交的所有内容进行交互式变更,其中添加了Voldemort以添加其他内容或根本不添加任何内容。
答案 0 :(得分:2)
结帐git filter-branch
Progress<T>
。
答案 1 :(得分:1)
使用BFG Repo Cleaner,Array#zip
比[{1}}更快,更容易使用。
要在所有文件中使用文字git filter-branch
替换所有出现的Voldemort
,您只需:
*** REMOVED ***
答案 2 :(得分:0)
我感谢Ewan Mellor指出我正确的方向,但答案非常小,我认为这需要更多细节。
如果您在执行此操作之前对repo进行了新的克隆,请确保您拥有所有遥控器的本地分支(例如git checkout master; git checkout develop; git checkout feature/some-undone-feature
等)。
> git filter-branch --tree-filter "~/purge.sh" \
--msg-filter "sed -e 's/voldemort/<word removed due to lawsuit>/gI'" \
--tag-name-filter "cat" \
-- --all
清除脚本(可能是一行,但它更干净):
#!/bin/bash
files=$(grep -rli 'voldemort')
for file in ${files}; do
sed -i -e 's/voldemort/<word removed due to lawsuit>/gI' ${file}
done
既然你已经完成了,你会想要检查这些问题:
git filter-branch
所做的备份。--tree-filter "~/purge.sh"
~/purge.sh
)运行--tree-filter ...
脚本
voldemort
(grep ... 'voldemort'
)-rli
)for file in ${files}; do
)
voldemort
的每个实例替换为该文件中的<word removed due to lawsuit>
(sed ... -e s/.../.../ ${file}
)-i
)--msg-filter "sed -e 's/voldemort/<word removed due to lawsuit>/gI'"
voldemort
替换单词短语<word removed due to lawsuit>
的每个实例(sed -e s/.../.../
)/gI
)--msg-filter ...
--tag-name-filter "cat"
-- --all
您可能想知道我们为什么不在sed -i -e 's/voldemort/<word removed due to lawsuit>/gI'
中的每个文件上执行--tree-filter
。原因是因为很多较慢。我认为因为它在每次提交中重写每个文件...即使不能命名的单词不在文件中。它加快了这个过程(至少10倍,可能是100倍,不想等待第一种方式完成),首先通过grep -rli 'voldemort'
获取问题文件列表。