为什么我的git仓库这么大?

159

145M = .git/objects/pack/

我编写了一个脚本,从每个分支的末尾向后退,将每个提交及其前一个提交之间的差异大小相加。我得到了129MB的结果,这是未经压缩的,并且没有考虑跨分支相同文件和分支之间的共同历史。

Git会考虑所有这些因素,因此我期望存储库要小得多。那么为什么.git这么大呢?

我已经执行了以下操作:

git fsck --full
git gc --prune=today --aggressive
git repack

关于有多少个文件/提交,我有19个分支,每个分支大约有40个文件。共287次提交,可使用以下命令查找:

git log --oneline --all|wc -l

存储这些信息不应该占用数十兆字节的空间。


6
Linus建议使用这种方法代替过于激进的垃圾回收。这样做会产生明显的差异吗?git repack -a -d --depth=250 --window=250 - Greg Bacon
谢谢gbacon,但没有区别。 - Ian Kelling
2
这是因为你缺少了-f选项。http://metalinguist.wordpress.com/2007/12/06/the-woes-of-git-gc-aggressive-and-how-git-deltas-work/ - spuder
1
git repack -a -d 将我的 956MB 仓库压缩至 250MB。非常成功!谢谢! - AlexGrafe
我发现的一个警告是,如果你有git子模块,则子模块的.git存储库会显示在超级模块的.git目录中,因此du可能会误导您认为超级模块很大,而实际上是一个子模块,下面的答案需要在子模块目录中运行。 - esmit
14个回答

1
如果您意外添加了大量文件并将它们暂存,而没有提交它们,则可能会发生这种情况。在一个 rails 应用程序中,当您运行 bundle install --deployment 并意外地执行了 git add .,然后您会看到所有添加到 vendor/bundle 下的文件,您可以取消暂存它们,但是它们已经进入了 git 历史记录,因此您必须应用 Vi's answer 并将 video/parasite-intro.avi 更改为 vendor/bundle,然后运行他提供的第二个命令。
您可以通过 git count-objects -v 查看差异,在我应用脚本之前,大小包为 52K,应用后为 3.8K。

1
我已经创建了一个新的实现,来替代最初在this answer中提供的perl脚本(该脚本后来被重写为rust)。在对那个perl脚本进行了大量调查之后,我意识到它有多个错误:
  • 路径中包含空格时出错
  • --sum无法正常工作(它实际上没有将所有增量加起来)
  • --directory无法正常工作(它依赖于--sum
  • 如果没有--sum,则会报告给定路径的实际上是随机对象的大小,这可能不是最大的一个

因此,我最终完全重写了脚本。它使用相同的git命令序列(git rev-listgit cat-file),但然后正确处理数据以提供准确的结果。我保留了--sum--directories功能。

我还将其更改为报告文件的“磁盘”大小(即在git存储库中的压缩大小),而不是原始文件大小。这似乎更相关于手头的问题。(如果有人因某种原因想要未压缩的大小,则可以选择此选项。)
我还添加了一个选项,只报告已删除的文件,假设仍在使用的文件可能较不重要。(我做这件事的方式有点黑客式;欢迎提供建议。) 最新脚本在这里。如果这是好的StackOverflow礼节,我也可以将其复制到这里?(它大约有180行。)

不错。这比我的原始脚本可读性高多了。我借鉴了你使用 %(objectsize:disk) 的技巧。 - piojo
是的,将脚本包含在内绝对被视为良好的礼仪。我曾认为这实际上是某种规则,但我在帮助中心中找到网站规则有些困难... - SamB

1

值得检查stacktrace.log。它基本上是一个用于跟踪失败提交的错误日志。我最近发现我的stacktrace.log文件大小为65.5GB,而我的应用程序大小为66.7GB。


-1

创建新分支,当前提交为初始提交,所有历史记录都被清除以减少Git对象和历史记录的大小。

注意:在运行代码之前,请阅读注释。

  1. git checkout --orphan latest_branch
  2. git add -A
  3. git commit -a -m “Initial commit message” #提交更改
  4. git branch -D master #删除主分支
  5. git branch -m master #重命名分支为master
  6. git push -f origin master #推送到主分支
  7. git gc --aggressive --prune=all #删除旧文件

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接