Git对我的工作流程至关重要。我在带有3GB内存的四核机器上运行Windows XP上的MSYS Git,通常它具有响应性和灵活性。
突然出现问题,从Git Bash命令提示符运行任何命令需要> 30秒,包括ls
或cd
。有趣的是,从bash提示符看起来像ls
运行相当快,我可以看到ls
的输出,但是提示返回需要大约30秒。如果我切换到Windows命令提示符(通过从开始菜单运行cmd
)git相关命令也需要永远,甚至只是运行。例如git status
可能会在发生任何事情之前花一分钟时间。有时这些过程根本无法完成。
请注意,我安装了“MSYS Git”以及MinGW
和make
之类的常规“MSYS”。
我认为该问题与位于sh.exe
的{{1}}有关。当我从bash提示符运行C:\Program Files\Git\bin
时,或者当我从Windows提示符调用ls
时,任务管理器最多会显示四个git
个进程实例。
我在等待sh.exe
返回,您可以看到任务管理器已ls
正在运行,有四个git.exe
实例:
如果sh.exe
位于ctrl-c
中间,我有时会收到包含以下内容的错误:
ls
或sh.exe": fork: Resource temporarily unavailable
0 [main] sh.exe" 1624 proc_subproc: Couldn't duplicate my handle<0x6FC> fo
r pid 6052, Win32 error 5
sh.exe": fork: Resource temporarily unavailable
:
$ git status
git status
我可以解决这个问题,以便git再次快速运行,如果是这样的话?
我尝试过的事情:
我非常想不擦拭我的盒子并重新安装Windows,但如果我不能解决这个问题,我会的。如果我需要> 30秒才能运行sh.exe": fork: Resource temporarily unavailable
sh.exe": fork: Resource temporarily unavailable
sh.exe": fork: Resource temporarily unavailable
sh.exe": fork: Resource temporarily unavailable
或git status
答案 0 :(得分:7)
通常,当一个程序花30秒钟做一些应该是瞬时的事情时,它更可能是I / O超时问题,通常是网络,而不是你的CPU速度或你拥有的RAM量。您可能想知道网络是如何参与的,但这是一个合理的问题(我不知道您的系统)。
Msysgit安装一个特殊的提示符,它运行一个特殊的函数__git_ps1
,在提示符中显示一些有用的信息。你可以使用echo $PS1
看到这个,对于我的系统,它显示:
$ echo $PS1
\[\033]0;$MSYSTEM:\w\007 \033[32m\]\u@\h \[\033[33m\w$(__git_ps1)\033[0m\] $
这些额外信息是完全可选的,您可以将其关闭。所以在Msysgit窗口中尝试以下内容:
$ PS1='$ '
$
这会将提示重置为默认值$
,而不是尝试在提示符内运行和命令。如果这可以解决您的延迟问题,那么它很可能是__git_ps1
函数。尝试手动运行:
$ __git_ps1
(master)
并查看返回所需的时间。
您可以通过从__git_ps1
删除调用C:\Program Files\Git\etc\profile
的行来解决此问题:
#Comment the lines below
#PS1='\[\033]0;$MSYSTEM:\w\007
#\033[32m\]\u@\h \[\033[33m\w$(__git_ps1)\033[0m\]
#$ '
答案 1 :(得分:7)
所以我们也遇到了这个问题,我认为我们最终将其追溯到msys的Windows安全模型的实现。我将尝试发布该问题的简短摘要:
屏幕截图: 堆栈的卡住sh.exe的痕迹。注意当msys-1.0.dll调用NetServerEnum()
时当sh.exe被阻止30秒时,这就是正在进行的操作。因此NetServerEnum()
仅在msys
的{{1}} get_lsa_srv_inf()
get_logon_server()
中调用,get_logon_server_and_user_domain()
调用create_token()
和seteuid()
调用在setuid()
中,由setuid()
中的{{1}}调用,由{{1}}调用。
因此,最初发生的是当msys DLL初始化并且sh.exe试图调用{{1}}时,msys会尝试忠实地遵守Windows安全模型并尝试从您的域中查找域服务器列表域/工作组。不幸的是,与Linux不同,对于Windows而言,这是一个阻塞调用,需要5到30秒才能完成/超时,实际上对于git来说实际上是不必要的。
我们的解决方案是使用安全性&#34;功能&#34;创建新的msys.dll。在winsup.cc中将security.cc:228设置为false即可禁用。 msysgit附带的bash / sh.exe与我们新版本的msys.dll不兼容,所以我们不得不从头开始编译一个新的bash.exe,不明白为什么。最终结果是sh.exe不再尝试进行这些NetServerEnum调用并运行lickity split。
答案 2 :(得分:3)
如果在运行多个同步Git命令时看到减速,可能是由于msysgit中的内核锁定问题
我们发现在某些情况下,git.exe的多个实例都会在同一个内核对象上(在WaitForSingleObject()
内)等待,这实际上意味着一次只能在系统上运行一个git命令
见这里:
使用ProcessExplorer,我们可以看到所有git.exe进程都停留在这里:
ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a
ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x732
ntoskrnl.exe!KeWaitForMutexObject+0x19f
ntoskrnl.exe!FsRtlCancellableWaitForMultipleObjects+0x5e
ntoskrnl.exe!FsRtlCancellableWaitForSingleObject+0x27
这似乎与这个问题有关:http://code.google.com/p/msysgit/issues/detail?id=320因为它不是Git而是伪Linux运行时(mingw)似乎包含问题。
我们将用于运行应用程序的用户帐户从SYSTEM更改为交互式用户帐户,并且内核对象等待消失:
健康的git.exe处理
因此,您看到的减速可能与某种内核对象争用有关 - 只有当前一个git命令释放内核锁时,其他命令才能运行。
尝试更改运行git命令的用户帐户,看看这是否解决了问题 - 它为我们做了。
答案 3 :(得分:2)
虽然格雷格的答案解决了眼前的速度问题,但我觉得它只是掩盖了问题而没有解决问题。
我开始慢慢运行git bash并按照Greg描述的步骤确定__git_ps1
是罪魁祸首。
而不是修改命令提示信息(我发现它显示的信息很有用)我找到了一个适合我的解决方案,在博客文章中有描述:
Solution to slow Git bash when logged in as a domain user
在网上搜索了一下,我发现git使用了默认的家, 在我的帐户上设置为网络帐户。这就是git会的 一直看这个目录,导致延迟。
为了解决这个问题,我创建了一个本地用户环境变量,覆盖 默认值,并将其设置为指向的%USERPROFILE% C:\用户[用户名]
同样的解决方案也发布在SO answering a similar question上。
添加环境变量将git返回到全速,我仍然可以获得命令行信息。
答案 4 :(得分:0)
我在Windows XP计算机上的处理问题很慢。有时候进程分叉需要几分钟。
我的修复是清空计算机的TEMP文件夹。计算机是一种共享资源,并且在那里累积了多年的文件。
答案 5 :(得分:0)
如果sh挂起在NetServerEnum中枚举登录服务器,请尝试将LOGONSERVER环境变量设置为实际的登录服务器。