Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从git';在保留尽可能多的历史记录的同时,是否保留历史记录?_Git - Fatal编程技术网

如何从git';在保留尽可能多的历史记录的同时,是否保留历史记录?

如何从git';在保留尽可能多的历史记录的同时,是否保留历史记录?,git,Git,TL;DR:我们的git存储库中有一个短语必须从历史中删除,而不仅仅是分支机构的负责人。除了将其从开发和创建新存储库的负责人中删除之外,还有什么其他方法?我们希望尽可能多地保留历史 背景 出于令人讨厌的法律原因,我和我的团队必须从我们的代码库中删除一个单词的所有实例(我们称之为伏地魔只是为了好玩和相关性)。令人恼火的是,我们不仅需要从分支的顶端删除伏地魔,我们还需要从我们存储库中的每个提交中删除它(这场诉讼的意思是“没有开发人员能够合理地恢复到伏地魔在代码中的状态”) 我们不再使用伏地魔了,但是

TL;DR:我们的git存储库中有一个短语必须从历史中删除,而不仅仅是分支机构的负责人。除了将其从开发和创建新存储库的负责人中删除之外,还有什么其他方法?我们希望尽可能多地保留历史

背景 出于令人讨厌的法律原因,我和我的团队必须从我们的代码库中删除一个单词的所有实例(我们称之为伏地魔只是为了好玩和相关性)。令人恼火的是,我们不仅需要从分支的顶端删除伏地魔,我们还需要从我们存储库中的每个提交中删除它(这场诉讼的意思是“没有开发人员能够合理地恢复到伏地魔在代码中的状态”)

我们不再使用伏地魔了,但是代码中有一些地方仍然像注释一样提到伏地魔。(是的,作为诉讼的一部分,我们必须从代码中删除侵权评论。)

最初的计划是清除不能提及的单词,然后创建一个新的存储库,并将当前状态作为初始提交。但我们不想失去所有的历史!所以我们想知道是否有办法避免这种情况

那么,问题是我们如何从历史中删除伏地魔这个不可提及的词,同时尽可能多地保留历史1?此外,我们可以做些什么来确保它不存在?我们想知道如何检查我们的工作,以确保它消失了

1:历史不是指具体的提交,我只是指能够查看文件的历史,知道谁做了什么,如果历史像git意义上的“重写历史”那样消失了,我觉得这是唯一的方法

回购协议状态信息
  • 目前developbranch没有伏地魔,但是在清除提交之前和之后我们都有“有意义的”提交
  • 可能只有最初的提交有任何添加伏地魔行的内容(因为我们从SVN迁移到git,伏地魔是在很久以前添加的)
  • 用伏地魔修改任何文件的唯一承诺可能是那些删除了它的人(就像我说的,这是很旧的东西)
对一种方法的猜测
似乎我们想做一些类似于git log的事情——补丁| grep‘Voldemort’来查找添加伏地魔的提交,然后对添加伏地魔的提交进行交互式重新基址编辑,以添加其他内容或什么都不添加。

查看
git筛选器分支
使用,它比git filter branch更快更容易使用

要将所有文件中出现的
伏地魔
替换为删除的
*********
,您只需:

% echo 'Voldemort' > badwords.txt
% bfg --replace-text badwords.txt myrepo.git

我感谢伊万·梅勒为我指出了正确的方向,但答案很小,我认为这需要更多的细节


提醒 如果您在执行此操作之前重新克隆了repo,请确保您拥有所有远程设备的本地分支(例如,
git checkout master;git checkout develope;git checkout feature/some undone feature
等)


我们所做的
>git筛选器分支--树筛选器“~/purge.sh”\
--msg过滤器“sed-e's/voldemort//gI”\
--标签名称过滤器“cat”\
----全部
清除脚本(可能只有一行,但更简洁,如下所示):

#/bin/bash
文件=$(grep-rli“伏地魔”)
对于${files}中的文件;做
sed-i-e's/voldemort//gI'${file}
完成

下一步 完成后,您需要检查以下问题:

  • :这将显示如何删除
    git filter branch
    生成的备份
  • :这将确保您在本地回购协议中没有恶意言论。这在我们的案件中是必要的,因为如果坏消息出现在我们的笔记本电脑上,公司可能会被起诉,并且/或者如果他们发现伏地魔软件,他们可能会执行远程擦除。你可能想在你的远程回购上运行它,但是如果你不能的话,那么你可以做一个新的(用一个稍微不同的名称或URL,以确保没有人错误地推到它或合并,从而取消你所有的努力工作!)

  • 解释
    • --树过滤器“~/purge.sh”
      • 对于每个提交,针对工作树运行
        ~/purge.sh
        脚本(
        --tree filter…
        • 列出包含伏地魔的文件列表(
          grep…“伏地魔”
        • 从这里递归地列出名称(而不是内容),不考虑大小写(
          -rli
        • 对于列表中的每个文件(
          对于${files}中的文件;do
          • 在该文件(
            sed…-es/../../${file}
            )中将单词短语
            voldemort
            的每个实例替换为
          • 在没有备份的情况下就位(
            -i
    • --msg过滤器“sed-e's/voldemort//gI'”
      • (sed-e
        s/../…/
        )替换单词短语
        voldemort
        的每个实例
      • 即使一行有两个,也不考虑大小写(
        /gI
      • 在提交消息中--msg filter…
    • --标签名过滤器“cat”
      • 对于每个标记,在新提交时将其重命名为其旧名称(如果不存在此名称,标记将不会继续)
    • --all
      • 对存储库中的每个提交执行此操作(是的,即两个破折号后跟一个空格,然后再加两个破折号)

    关于性能的说明 你可能想知道,为什么我们不简单地对
    --tree filter
    中的每个文件执行
    sed-i-e's/voldemort//gI'
    > 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