如何在特定提交之前截断git历史记录?

时间:2017-04-19 05:47:56

标签: git

错误地将所有二进制文件添加到我的git历史记录中,我有一个大小约为50 MB的git repo。如何从历史记录中删除特定提交之前的所有提交?例如,具有以下历史记录,我想删除C2之前的所有提交,就像C2是第一次提交一样。 (实际上C2可能是合并提交)

我已经尝试了git-filter-branch,它根本不能做我需要的东西,this脚本似乎很安静,虽然它删除了整个历史;留下一个提交。

History

3 个答案:

答案 0 :(得分:1)

实现此目的的一种方法是使用git filter-branch --parent-filter,并从父母集中删除C1。

git filter-branch --parent-filter "sed -e 's/-p $(git rev-parse C1)//'" -- --all

$(git rev-parse C1)用于获取完整的40个字符的提交ID,如果您已经知道它是什么,则可以替换它。

如果某些C1的祖先是通过合并等提取的,你也可以用同样的方式删除它们,或者使用更复杂的脚本,如

git filter-branch --parent-filter '
    for i in $(cat); do
        if [[ $i = -* ]] || git merge-base --is-ancestor "$i" C1; then
            continue
        else
            echo -n " -p $i"
        fi
    done
' -- --all

答案 1 :(得分:0)

我会建议一个新的孤儿分支,然后采摘樱桃。

通过这种方式,您可以检查所有内容,甚至可以将旧状态作为备份保留在您的计算机上。

要开始工作,请在C2

点创建一个新分支
$ git checkout <Hash of C2>
$ git checkout --orphan new-master

git checkout --orphan将创建一个没有父母的新分支。

此时使用

添加或删除文件
  • git add为新的第一次提交添加文件
  • git rm --cached删除新的第一次提交的文件,但将它们留在硬盘上
  • git rm删除第一次提交以及硬盘驱动器的文件

确保所有文件都存在,这些文件将在以后的提交中更改,否则挑选可能会非常混乱。

现在git commit准备好新的初始提交。

最后但并非最不重要只需通过cherry-picking重新应用所有其他提交正确的范围。

$ git branch new-starting-point # for future reference
$ git cherry-pick ^C2 master

对需要新历史记录的所有其他分支重复这些步骤。

$ git checkout -b new-server new-starting-point
$ git cherry-pick ^C2 server

如果您想检查正确性,可能需要执行一些git diff master new-master

要清除空间,请删除所有旧分支(以便不再可以访问旧提交)。在以下步骤中,您可能会丢失数据。确保你仍然拥有你想要的一切:git gc应该是你需要的所有空间。

答案 2 :(得分:0)

使用git filter-branch,而不是删除整个提交,您可以从提交中删除二进制文件:

git filter-branch --index-filter 'git rm --cached -rf bin/ && git rm --cached -f ./a.out' -- --all