为什么git在使用"太多打开的文件"进行推送/获取时失败?

时间:2013-03-13 01:29:39

标签: linux git config

我遇到了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   错误:无法创建管道:打开的文件太多   致命:send-pack:无法分离边带解复用器

有人可以回答为什么会发生这种情况吗?我没有对我的git配置进行任何最近的更改,并且已经手动验证了。

2 个答案:

答案 0 :(得分:11)

有两条类似的错误消息:

EMFILE: Too many open files
ENFILE: Too many open files in system

看起来你正在获得EMFILE,这意味着超出了单个进程的文件数。因此,检查vi是否可以打开文件是无关紧要的 - vi将使用自己独立的文件表。通过以下方式检查您的限制:

$ ulimit -n
1024

因此,在我的系统中,单个进程中有1024个打开文件的限制。您不需要询问您的系统管理员(请不要使用首字母缩略词SA,它太不透明;如果您必须缩写,请使用“sysadmin”)来提高限制。

您可能希望通过在strace下运行Git来检查Git打开的文件。

这可能是Git或库中的错误,或者可能是你正在使用旧版本的东西,或者它可能是更奇怪的东西。首先尝试strace查看它打开的文件,然后检查Git是否关闭这些文件。

从Hazok更新:

使用上述建议后,发现错误是由太多松散的物体引起的。松散的物体太多了,因为git gc没有经常运行。

答案 1 :(得分:0)

为什么会这样?

来自the git documentation

<块引用>

当存储库中的松散对象大约超过这么多时,git gc --auto 会将它们打包。一些 Porcelain 命令使用此命令不时执行轻量级垃圾收集。 默认值为 6700。

这里的“Some Porcelain 命令”包括 git pushgit fetch 等。所以如果最大打开文件限制 ulimit -n < 6700,你最终会被 git gc --auto一旦你在一个 git 仓库中得到了大约 6700 个松散的对象。

我很着急。如何解决?

如果你有足够的权限来调整系统ulimit:

$ sudo ulimit -n 8192

否则,您可以通过设置 git gc 禁用 git config gc.auto=0,这样您就可以将本地提交推送到远程,删除存储库,然后将其克隆回来,而不会产生数千个松散对象。

我们怎样才能防止这种情况再次发生?

设置 git config --global gc.auto=200,其中 200 是小于最大打开文件限制的某个值。如果您选择的值太小,git gc 会运行太频繁,因此请明智地选择。

如果您设置 gc.auto=0,除非您手动运行 git gc,否则永远不会打包松散的对象。所以同一个目录下可能会积累成百上千的文件,这可能是一个问题,特别是对于机械硬盘或Windows用户。 (另见:How many files in a directory is too many?Is it OK (performance-wise) to have hundreds or thousands of files in the same Linux directory?)。