我遇到一个Git问题,我收到以下消息:
> git fetch
error: cannot create pipe for ssh: Too many open files
fatal: unable to fork
系统管理员已经增加了我的文件限制,但它并没有纠正这个问题。另外,我用vi.
创建新文件没有问题。当尝试推送一个新分支时,我得到一个类似的消息:
git push origin test_this_broken_git错误:无法创建管道:打开的文件太多Fatal: send-pack:无法fork off边带解复用器
谁能确切地回答为什么会发生这种情况?
有两个类似的错误消息:
<>之前EMFILE:打开的文件太多ENFILE:系统中打开的文件太多之前看起来您得到了EMFILE
,这意味着超出了单个进程的文件数量。因此,检查vi
是否可以打开文件是无关紧要的- vi
将使用自己的,单独的文件表。检查你的极限:
所以在我的系统上,在单个进程中有1024个打开文件的限制。你不需要询问你的系统管理员(请不要使用缩写SA,它太不透明;如果必须缩写,使用"sysadmin")来提高限制。
您可能希望通过在strace
下运行Git来检查Git打开了哪些文件。
这可能是Git或库中的错误,也可能是你使用的是旧版本的东西,或者可能是更奇怪的东西。先试试strace
,看看它打开了哪些文件,并检查Git是否关闭了这些文件。
从Hazok更新:
在使用上述建议后,发现错误是由太多松散对象引起的。因为git gc
没有经常运行,所以有太多松散的对象。
为什么会发生这种情况?
来自git文档:
当存储库中的松散对象超过这个数目时,git gc——auto将打包它们。一些Porcelain命令使用这个命令不时地执行一个轻量级的垃圾收集。默认值为6700
Here "Some Porcelain commands"包括git push
, git fetch
等。所以如果最大打开文件限制ulimit -n
<如果你在一个git仓库中有6700个松散对象,你最终会被git gc --auto
阻止。>
如果您有足够的权限来调整系统ulimit:
$ sudo ulimit -n 8192
否则,您可以通过设置git config gc.auto 0
来禁用git gc
,这样您就可以将本地提交推送到远程,删除repo,并将其克隆回来,而不会产生数千个松散对象。
我们怎样才能防止这种情况再次发生?
设置git config --global gc.auto 200
,其中200是小于最大打开文件限制的某个值。如果你选择一个太小的值,git gc
会运行得太频繁,所以明智地选择。
如果您设置gc.auto=0
,松散对象将永远不会被打包,除非您手动运行git gc
。因此,在同一个目录中可能会积累数十万个文件,这可能是一个问题,特别是对于机械硬盘驱动器或Windows用户。(参见:一个目录中有多少文件才算太多?