Git拉取致命错误:内存不足,malloc失败。

11

我在https://bitbucket.org/上有一个代码仓库。

几天前,由于一个错误,大量图像文件被推送到代码仓库中。然后再通过另一次推送删除了这些文件。之后,代码仓库一直工作正常,但今天当我尝试从代码仓库拉取时:

$ git pull
Password for 'https://repo@bitbucket.org': 
warning: no common commits
remote: Counting objects: 4635, done.
remote: Compressing objects: 100% (1710/1710), done.
fatal: Out of memory, malloc failed (tried to allocate 4266852665 bytes)
fatal: index-pack failed  

我尝试过:

  1. git config --global pack.windowMemory 1024m
  2. $ git count-objects -v count: 9 size: 48 in-pack: 4504 packs: 1 size-pack: 106822 prune-packable: 0 garbage: 0

但是没有成功,我不确定接下来该采取什么措施...
代码库的大小应该在10-20m左右,我该怎么做?

更新1
我执行了这些命令:

$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch public/images/*' HEAD
Rewrite a1c9fb8324a2d261aa745fc176ce2846d7a2bfd7 (288/288)
WARNING: Ref 'refs/heads/master' is unchanged

$ git push --force --all
Counting objects: 4513, done.
Compressing objects: 100% (1614/1614), done.
Writing objects: 100% (4513/4513), 104.20 MiB | 451 KiB/s, done.
Total 4513 (delta 2678), reused 4500 (delta 2671)
remote: bb/acl: ayermolenko is allowed. accepted payload.
To https://repo@bitbucket.org/repo.git
 + 203e824...ed003ce demo -> demo (forced update)
 + d59fd1b...a1c9fb8 master -> master (forced update)

拉动后正常工作:

$ git pull
Already up-to-date.

但是当我尝试克隆代码库时,我遇到了以下问题

~/www/clone$ git clone git@bitbucket.org:repo.git
Cloning into 'clone'...
remote: Counting objects: 5319, done.
remote: Compressing objects: 100% (1971/1971), done.
fatal: Out of memory, malloc failed (tried to allocate 4266852665 bytes)
fatal: index-pack failed

更新2
非常遗憾,我没有找到所有的大文件。还有一些留下了。所以我请求支持团队删除这个仓库的所有日志。

更新3
最终我不得不删除旧的并创建一个新的仓库。


1
糟糕,他们(BitBucket)没有彻底清理你的 repo。你的解决方案不错,尤其是比我的实现更为实用,即使你需要改变远程 repo 地址。 - VonC
我已经厌倦了寻找一个坏牙齿 ;) - Elmor
4个回答

10
在我的情况下,问题很简单,就是在一个1GB的RAM盒子上尝试拉取一个大存储库而没有swap。我按照这篇教程 https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-14-04 在服务器上创建了一些交换空间,然后问题得到了解决。
他们的“更快”的方法:
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

您可以通过添加到 /etc/fstab 来使这些更改永久:

/swapfile   none    swap    sw    0   0

他们建议在/etc/sysctl.conf中添加:
vm.swappiness=10
vm.vfs_cache_pressure = 50

我使用了他们的“更快的方式”,但是使用了1G,它解决了我的问题,谢谢! - crobicha
这正是我需要的,不仅要打包和推送,还要进行克隆。 - Sean Halls
哇!谢谢,老兄,你救了我一命。 - Iman Mirzadeh

4
如果您是唯一使用此 repo 的人,您可以按照 "如何从 Git 提交历史记录中清除巨大文件?" 中描述的 git filter-branch 选项操作。
更简单的选择是将 repo 克隆到旧的提交,并强制推送它,如 "git-filter-branch 删除大文件" 中所述。
任何一种方法都会强制任何合作者将其本地 repo 重置为您发布的新状态。再次强调,如果您是唯一的合作者,则不是问题。

合作者不是问题。现在我遇到了克隆错误。请查看更新1。 - Elmor
1
@Elmor 然后您需要联系 BitBucket,让他们在您的 repo 上运行 'git gc'(如 https://dev59.com/XGXWa4cB1Zd3GeqPRuoM#11404097 中所提到的)。他们应该会自动运行它 (https://confluence.atlassian.com/pages/viewpage.action?pageId=287998264),但我不确定 git push --force 是否会触发该 git gc - VonC
2
@Elmor Plus,BitBucket可能不会清除最近删除的历史记录,因此您仍然可能需要联系BitBucket以进行更彻底的清理:git gc --prune=today --aggressive或者更多,如https://dev59.com/TXI-5IYBdhLWcg3wVW3v#1908476所述。 - VonC
谢谢,已经写信给Bitbucket的支持团队了。在等待他们的回复 ;) - Elmor

2
即使大型图像文件在推送后被删除,它们仍然存在于git历史记录中。建议强制从git历史记录中删除它们(我认为这是可能的,但涉及一个我不知道的复杂过程)。或者,在错误添加文件之前拉取存储库,对存储库进行修补以进行相关小修补,克隆该存储库,并将其用作您的主要git(可能需要使用转储/还原)。我不太清楚细节,但我确实读到过这是可能的

感谢您提供的一般指导 ;) - Elmor

0

最近我在一个代码库中遇到了这个问题。类似的错误提示,暗示着有一个大文件隐藏在代码库的某个地方。

Cloning into 'test_framework'...
remote: Counting objects: 11889, done.
remote: Compressing objects: 100% (5991/5991), done.
Receiving objects:  66% (7847/11889), 3.22 MiB | 43 KiB/sremote: fatal: Out of memory, malloc failed     (tried to allocate 893191377 bytes)
remote: aborting due to possible repository corruption on the remote side.
fatal: early EOFs:  66% (7933/11889), 3.24 MiB
fatal: index-pack failed

为了解决这个问题,我暂时创建了一个大型交换驱动器(超过服务器要求的893191377字节),遵循此处的方法2: http://www.thegeekstuff.com/2010/08/how-to-add-swap-space/ 这使我成功克隆并删除了罪魁祸首(某人上传了一个SQL转储文件)。您可以使用:
git filter-branch --tree-filter 'rm -rf dumpfile.sql' HEAD

从git仓库中删除文件。


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