通过清除存储库历史记录git可用磁盘空间

时间:2013-04-17 10:13:46

标签: git

所以我和一些朋友一起工作,我们都是git的新手,其中一个提交了大量的外部二进制文件,这会减慢存储库的速度,占用大量的磁盘空间。

我们刚刚启动了这个项目,所以除了自述文件之外没有什么重要的。所以我们要做的是将存储库历史记录清除到当前状态。

So basicly it looks this:

Head -> A -> B -> C    total disk size 45 MB, 1 file, 300 deleted files

And we want this:

Head -> A              total disk size 1 kB, 1 file, 0 deleted files

显而易见的解决方案是创建一个新的存储库,然后将自述文件复制到新的存储库中。但是,如果有GIT命令可以做到这一点,我想学习教育/好奇心。

我一直在尝试使用Rebase命令,但它似乎仍然保留了旧历史记录及其数据,这让我感到困惑,因为如果重新绑定不会从存储库中删除数据,那么您可能也不会使用它。

我一直在谷歌搜索关于这个问题的其他帖子,我怀疑你不能用git这样做。但是我想确认一下。

是的,它是github上的远程目录

感谢您的帮助。

因此,对于我的解决方案,我选择这样做:

rebase using tortoisegit
squash all commits
then using git bash:
git reflog expire --all --expire-unreachable=now
git gc --aggressive --prune=now
git push origin master --force

本地存储库历史记录似乎不希望缩小磁盘大小。但是,再次克隆存储库会显示所需的结果和磁盘大小。存储库日志也是如此。

感谢您的回复。有趣的Rebase似乎非常强大。

3 个答案:

答案 0 :(得分:7)

重新绑定(git rebase -i --root,如果你没有恢复错误的提交只是删除它的行,如果你这样做,用破坏提交压缩坏提交)或使用filter-branch将清除你的分支的数据历史,但不会让它完全从存储库中消失。

这是因为出于安全和可追溯性的原因,git会保留一个reflog(可以git log -g显示),它跟踪你做的每一次提交,无论它是否仍然是祖先图的一部分。

克隆已过滤的repo不会克隆隐藏的数据,您也可以使用以下命令将其删除:

git reflog expire --all --expire-unreachable=now
git gc --aggressive --prune=now

通常不建议使用这些命令,并且未引用的提交无论如何都会在30天后到期,但由于您的存储库几乎是新的,因此您不会冒太大的风险。

答案 1 :(得分:4)

您无需完全丢失历史记录。您可以使用filter-branch重写它。这是一个非常具有破坏性的命令,所以先复制一份。此示例将浏览您的历史记录,删除所有jar个文件。

git filter-branch --tree-filter 'git rm **/*.jar'

调整此项以匹配意外添加的任何巨型文件。请注意,修改提交会更改其ID,以便人们可能希望在此之后重新克隆存储库,以避免可怕的冲突。您还需要--force推回存储库,因为git会抱怨(正确地)历史记录已经发生了很大的变化。

在决定进行垃圾收集之前,您的本地仓库可能不会立即缩小尺寸。

答案 2 :(得分:1)

您可能需要查看Squashing all Git commits into a single commit。这也引用了一个堆栈溢出问题 - 可能被称为重复 - 在这里:How to squash all git commits into one?

Wincent在第一个链接中提到的解决方案大约是页面的一半。本地快速测试表明它确实像宣传的那样工作。作为参考,Wincent建议:

git update-ref -d refs/heads/master
git commit -m "Initial import"

FWIW,您可能需要运行git gc --prune=now来清理所有未引用的对象。当你向上推新主人时,你需要使用--force。在尝试任何此类操作之前,您应该创建一个备份。 : - )