在Debian上运行git命令&;WSL上的Ubuntu对于大型项目来说速度非常慢

在Debian上运行git命令&;WSL上的Ubuntu对于大型项目来说速度非常慢,git,git-bash,windows-subsystem-for-linux,Git,Git Bash,Windows Subsystem For Linux,我们有一个非常大的项目,总共有近15000个提交。我使用WSL在Windows机器上运行Debian9.3。我的git版本是2.17.0 当我运行诸如git status之类的命令时,至少需要20秒才能完成。即使没有改变 我尝试过多个较旧版本的git,甚至尝试过Ubuntu,但我仍然体验到同样的结果。我试过在这里和其他网站上运行各种帖子中的一系列命令,但都不起作用 有趣的是:当我在Windows上打开cmd.exe或Git Bash时,运行Git status不到一秒钟 这可能是什么原因造成的?

我们有一个非常大的项目,总共有近15000个提交。我使用WSL在Windows机器上运行Debian
9.3
。我的git版本是
2.17.0

当我运行诸如
git status
之类的命令时,至少需要20秒才能完成。即使没有改变

我尝试过多个较旧版本的git,甚至尝试过Ubuntu,但我仍然体验到同样的结果。我试过在这里和其他网站上运行各种帖子中的一系列命令,但都不起作用

有趣的是:当我在Windows上打开
cmd.exe
或Git Bash时,运行
Git status
不到一秒钟

这可能是什么原因造成的?如何解决此问题?

2019年6月更新:,并提供完整的系统调用兼容性。
这将大大提高Git命令的性能


原始答复2018:

Git在没有任何中间层的主机上执行时工作得最好

例如,如果您的回购协议位于共享文件夹上,Git的速度会慢得多。
对于WSL,repo是本地访问的,但是通过将各种Linux文件系统操作转换为NT内核操作

这足以解释性能下降的原因,特别是在大型Git存储库上 另外,请确保您的
$PATH
没有引用具有Windows可执行文件的文件夹,这些可执行文件可能会被调用,而不是Linux可执行文件

可能的原因:

  • 文件系统仿真(慢):
  • :确保在基本shell提示符中测试命令,而不进行任何复杂的
    PS1
    计算
  • :尝试从AV扫描中排除(用于测试)WSL管理的文件系统

您可以使用env var获得一些分析细节:

$ GIT_TRACE_PERFORMANCE=1 git status -sb -uno
08:51:54.525808 read-cache.c:1889       performance: 0.000330659 s: read cache .git/index
08:51:54.528532 preload-index.c:112     performance: 0.002669928 s: preload index
08:51:54.528667 read-cache.c:1447       performance: 0.000109768 s: refresh index
08:51:54.528892 diff-lib.c:250          performance: 0.000056516 s: diff-files
08:51:54.534630 diff-lib.c:527          performance: 0.005070461 s: diff-index
## wip/foo
08:51:54.536419 trace.c:420             performance: 0.013503141 s: git command: git status -sb -uno

在当前WSL的Thinkpad T460s上,以及虚拟盒Fedora 28上(无gui,Putty)

本地克隆的真实时间为

Fedora 3s, WSL 67s, MSYS2 65s
关闭Defender后,时间会下降到

WSL 11s, MSYS2 13s
所以

  • 没有GUI的虚拟盒Fedora速度最快
  • 防守者是昂贵的。排除git工作根目录
  • 如果WSL git工作目录位于~或/c/mnt下,则未发现实际差异

请随意重复这个小测试。

在我使用Ubuntu的WSL中,我体验到第一个“git status”命令比第二个慢得多。可能在第一次运行时就完成了缓存或索引。第二个“git状态”速度对我来说没问题。

  • 安装git for windows
  • 在wsl上安装git
  • 将此脚本添加到“/usr/local/bin”目录并将其命名为“git”:
特别是帮助我在WSL2中运行oh my zsh,它在每个命令之后运行“git status”

同样,像上面提到的那样关闭Defender也有一点帮助。

WSL2 WSL确实是一件有趣的事情gitspeed与读取/写入文件的文件系统密切相关

解决方案: 根据文件系统路径,确保使用的是
git
git.exe

~/.bashrc
的末尾添加以下代码段(用于Bash、ZSH和friends)

函数git(){
如果$(pwd-P | grep-q“^\/mnt\/c\/*”),则
git.exe“$@”
其他的
命令git“$@”
fi
}
如果您使用的是
fish
,则可以使用以下代码段:

函数git——包装git
如果pwd-P | grep-q“^\/mnt\/c\/*”
git.exe$argv
其他的
命令git$argv
结束
结束
在我的例子中,虽然我在WSL的文件系统上工作,但使用自定义的
git
命令修复了这个问题,看起来仍然有机会
git
在WSL的文件系统之外做一些工作

感谢Christoph Grabo(asaaki),他最初发布了此解决方案。


你有没有试过
git-gc
,然后
git-status
@nbari是的,速度也一样慢。如果
哪个git
,结果会是什么?@TarunLalwani
/usr/bin/git
15000次提交不应该减慢速度,除非提交的文件真的很大,比如Photoshop项目或图片等等。然而,通过这种方式引入,它听起来更像是某个地方的超时问题,而不是Git行为。您在执行命令时检查了CPU负载了吗?那么您的主要意思是,我不能通过WSL使用Git?不,
git
不会干扰我的Windows可执行文件。它位于我的本地驱动器上,这是一个500GB三星960 EVO,所以它应该足够快。请注意,我的其他项目有几百个提交和文件,速度非常快。@Mortenmolder是的,Git在任何层(网络层,或者,这里是翻译层)中使用时,都会比在裸机上使用时慢(这里是Git for Windows,作为Git.exe,直接在CMD中使用)有任何线索说明它为什么那么慢吗?我知道与NT内核对话比直接与NT内核(从NT内核)对话要慢,但我发现很难相信它会慢25-35倍(假设git.exe状态为1秒)。@MortenMoulder一些线索:I/O相关(),或AV(防病毒)相关:。或提示相关()@MortenMoulder没有问题。我将把这个问题留给其他可能没有停用Windows Defender的人回答。
性能:0.702618000 s:预加载索引
之后是
性能:16.311419000 s:刷新索引
Windows Defender为我关闭:-)我在提到的文件夹中创建了一个名为“git”的文件,我的git状态仍然需要很多时间,但是git.exe速度很快。我还继续向该文件添加了随机文本并保存了它,在运行git时我没有收到任何错误,这个脚本应该在什么时候执行?
Fedora 3s, WSL 67s, MSYS2 65s
WSL 11s, MSYS2 13s