将根提交移到后一个提交,丢弃以前的每个历史记录

时间:2014-09-11 08:25:38

标签: git

作为this question的延续,我想:

  • keep n last commit
  • 从历史记录中删除所有n + 1和之前的提交
  • 使提交n像新建的存储库

例如,请考虑以下提交树:

1-2-3-4-5

在下一次提交之后,我希望它是:

2-3-4-5-6

但是,不应再跟踪1中发生的情况。即:2现在应该是根。这是必需的,因为会涉及很多二进制文件,我不希望git存储应该已经消失的内容。使用git rebase + squash仍然会将文件保留在历史记录中,只有压缩的提交。

这个想法是使用git作为定期备份系统,支持最后n次提交。在现实中,将会有一个cron工作承诺每天都在改变。

2 个答案:

答案 0 :(得分:0)

我认为你想删除无法从提交对象访问的blob对象。这些对象称为无法访问或悬空对象。实际上Git已经提供了一个很好的清理机制,称为auto gc。您也可以手动运行git gc。它将压缩文件版本并删除几个月前无法访问的对象。压缩工作可能比你想象的要好。根据我的测试,它存储文件版本的差异,即使是二进制文件。

如果您需要更多手动和自定义行为,还有一些相关的命令,包括git fsckgit prunegit repackgit prune-packed

但我的建议只是将gc.reflogExpireUnreachablegc.reflogExpire缩短为1天,然后运行" git gc"期间,让git为你工作。但是我不确定它是否实用,因为我还没有测试过它。

附上一些参考文献。

http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery#Maintenance

  

有时,Git会自动运行一个名为“auto gc”的命令。最   当时,这个命令什么都不做。但是,如果有太多   松散的对象(不在packfile中的对象)或太多的packfiles,Git   推出一个完整的git gc命令。 gc代表垃圾   收集,命令做了很多事情:它收集所有   松散的物体并将它们放在包装文件中,它会巩固   packfiles到一个大的packfile中,它删除不是的对象   可以从任何提交到达,并且几个月。

http://git-scm.com/docs/git-gc

  

git gc在当前内部执行许多内务处理任务   存储库,例如压缩文件修订版(以减少磁盘空间)   并提高性能)并删除可能无法访问的对象   已经从先前的git add调用创建。

答案 1 :(得分:0)

我认为获得这个的最好方法是从2创建一个孤儿分支,然后以这种方式进行变基:

git checkout 2
git checkout --orphan newmaster # creates a new orphan branch with no parents
git commit -C 2 # commits all the contents from 2 using same commit message of 2
git rebase --onto HEAD 2 master # rebase all contents from master to this new branch
git push -f origin master:refs/heads/master # push the new master branch

注意我们在最后一个命令上使用-f(强制),这应该是一个例外,没有规则,所有这一切都应该在“冻结”的repo上完成,提交1现在将无法访问,任何blob或者如果没有剩余其他引用,则git gc将删除与该提交相关联的内容(您可以手动运行git gc,或者根据您的git服务器的设置自动运行)

另一种选择:使用git-filter-branch

如果你的问题是重文件占用太多的存储库空间,你不需要重写历史记录来从repostory中删除这些文件,git-filter-branch是为这种情况设计的工具,这是一个基本的例如:

git filter-branch --tree-filter 'rm path/to/heavyfile; true'

它重建当前分支的所有历史记录(例如master分支),但是,为每个提交执行bash命令,在这种情况下删除所有提交的/ path / to / heavyfile。当然,您可以改进脚本,例如,删除整个目录,重命名文件甚至调用自己的外部命令

最好的办法是,如果你犯了一些错误,可以轻松撤消此操作,撤消过滤器分支就像这样简单:

git reset --hard HEAD@{1}

有关git-filter-branch的更多信息:http://git-scm.com/docs/git-filter-branch

更多关于使用git重写历史记录:http://git-scm.com/book/en/Git-Tools-Rewriting-History