在Windows 7 x64上,Git Bash非常慢

时间:2010-12-19 20:58:56

标签: git bash windows-7 msysgit mingw32

我在开发一个小项目时一直在Windows和Ubuntu上使用Git,经常在两者之间来回翻转。问题是 Git Bash 一直变慢。

当我说慢时,我的意思是,运行cd需要8到25秒,运行git命令需要5-20秒,而ls最多可能需要30秒有时秒。毋庸置疑,这并不好玩,更不用说非生产性了。我知道Git在Windows上比较慢,但这太荒谬了。

对我来说暂时有效的一个解决方案是禁用我的网络连接(如this answer中所示),启动Git Bash,然后重新连接。有时它会在这样做之后继续快速运行数天,但性能总是最终会降低。我已经在msysgit讨论组,Stack Overflow,msysgit问题列表等中进行了数周的打开和关闭,但是我还没有找到有效的解决方案。

到目前为止,我已经尝试过了:

  • 添加Git&项目文件夹到病毒扫描程序的排除列表
  • 完全禁用我的病毒扫描程序(Kaspersky IS 2011)
  • 确保Outlook未运行(Outlook 2007)
  • 关闭所有其他应用程序
  • 以管理员身份运行Git Bash
  • 禁用网络连接,启动Git Bash并禁用连接
  • 禁用网络连接,启动Git Bash,重新启用连接(仅偶尔使用)
  • 正在运行git gc
  • 以上
  • 的组合

我确实读到有几个人成功禁用Bash完成,但理想情况下我想保持活跃。 msysgit的版本是1.7.3.1-preview20101002&操作系统是Windows 7 x64。可以预见,在Linux上运行相同的东西是快速的。我会专门使用Linux,但我也需要在Windows中运行东西(某些应用程序,测试等)。

有没有人遇到过类似的问题?如果是,那么潜在的问题是什么?解决方案是什么(如果有的话)?

这超出了Git存储库的范围,但仅供参考,我一直在使用Git的存储库非常小:最多4-50个文件。

23 个答案:

答案 0 :(得分:388)

通过运行三个命令设置一些配置选项,您可以在Windows上显着加快Git的速度:

git config --global core.preloadindex true
git config --global core.fscache true
git config --global gc.auto 256

注意:

  • core.preloadindex并行进行文件系统操作以隐藏延迟(更新:默认情况下在Git 2.1中启用)

  • core.fscache修复了UAC问题,因此您无需以管理员身份运行Git(更新:默认情况下在Git for Windows 2.8中启用)

  • gc.auto最小化.git /

    中的文件数量

答案 1 :(得分:88)

您的Bash提示中是否显示Git信息?如果是这样,也许你无意中对每一个命令做了太多的工作。为了测试这个理论,请尝试在Bash中进行以下临时更改:

export PS1='$'

答案 2 :(得分:75)

我的Windows主目录在网络上,我怀疑Git Bash命令首先在那里查找。果然,当我查看$ PATH时,它首先列出/ h / bin,其中/ h是Windows文件服务器上的共享,即使/ h / bin不存在。我编辑了/ etc / profile并注释掉了将其放在$ PATH中的导出命令:

#export PATH="$HOME/bin:$PATH"

这使我的命令运行得更快,可能是因为Git Bash不再通过网络查看可执行文件。我的/ etc / profile是c:\ Program Files(x86)\ Git \ etc \ profile。

答案 3 :(得分:36)

我发现网络驱动器是性能问题。 HOME指向网络共享速度缓慢。 我无法覆盖HOMEDRIVE,但这不是我所看到的问题。

通过右键单击设置环境变量 您的计算机在桌面上 - >属性 - >高级系统设置 - >环境变量 添加到用户变量部分

HOME=%USERPROFILE%

答案 4 :(得分:22)

在对Chris Dolan的回答的扩展中,我使用了以下替代PS1设置。只需将代码片段添加到〜/ .profile(在Windows 7上:C:/Users/USERNAME/.profile)。

fast_git_ps1 ()
{
    printf -- "$(git branch 2>/dev/null | sed -ne '/^\* / s/^\* \(.*\)/ [\1] / p')"
}

PS1='\[\033]0;$MSYSTEM:\w\007
\033[32m\]\u@\h \[\033[33m\w$(fast_git_ps1)\033[0m\]
$ '

这保留了彩色外壳的优点并显示当前分支名称(如果在Git存储库中),但在我的机器上显着更快,从0.75秒到0.1秒。

这基于this blog post

答案 5 :(得分:22)

虽然您的问题可能是基于网络的,但我个人通过两次修改加速了本地git status次呼叫十倍(7秒以上至700毫秒)。这是一个700 MB的存储库,包含21,000个文件和过多的大型二进制文件。

一个是启用并行索引预加载。从命令提示符:

git config core.preloadindex true
这将time git status从7秒改为2.5秒。

  

更新!

     

以下不再需要。从mysysgit 1.9.4起修补了这个补丁   https://github.com/msysgit/git/commit/64d63240762df22e92b287b145d75a0d68a66988
  但是,您必须通过键入
来启用此修复程序   git config core.fscache true

我还禁用了UAC和“luafv”驱动程序(需要重启)。这会禁用Windows Vista,7和8中的驱动程序,该驱动程序会重定向尝试写入系统位置的程序,而是将这些访问重定向到用户目录。

要查看有关这会如何影响Git性能的讨论,请阅读: https://code.google.com/p/msysgit/issues/detail?id=320

要禁用此驱动程序,请在regedit中将HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/luafv处的“开始”键更改为4以禁用驱动程序。然后,将UAC置于其最低设置“永不通知”。

如果禁用此驱动程序会让您保持警惕(应该),则会在与系统分区不同的驱动器(或分区)上运行替代方案。显然,驱动程序仅在系统分区上的文件访问上运行。我有一个第二个硬盘驱动器,并在我的C驱动器上运行此注册表修改时看到相同的结果,因为我在D驱动器上没有它。

此更改将time git status从2.5秒缩短至0.7秒。

您还可以关注https://github.com/msysgit/git/pull/94https://github.com/git/git/commit/d637d1b9a8fb765a8542e69bd2e04b3e229f663b,了解Windows中针对速度问题正在进行的其他工作。

答案 6 :(得分:16)

似乎完全卸载Git,重新启动(经典的Windows固化),并重新安装Git是治愈方法。我还清除了剩下的所有bash配置文件(它们是手动创建的)。一切都很快。

如果由于某种原因重新安装是不可能的(或可取的),那么我肯定会尝试更改Chris Dolan's answer中引用的PS1变量;它导致了某些操作的显着加速。

答案 7 :(得分:10)

我通过以“以管理员身份运行”启动cmd.exe解决了Windows 7 x64上的慢速Git问题。

答案 8 :(得分:8)

通过将core.preloadindex设置为true as recommended here,我看到了一个不错的改进。

答案 9 :(得分:5)

正如克里斯·多兰和威尔伯特的回答所指出的那样, PS1会减慢你的速度

我没有完全禁用(如Dolan所建议)或使用Wilbert提供的脚本,而是使用速度更快的“哑PS1”。

它使用(git symbolic-ref -q HEAD || git rev-parse --short HEAD) 2> /dev/null

PS1='\033[33m\]\w \n\[\033[32m\]$((git symbolic-ref -q HEAD || git rev-parse -q --short HEAD) 2> /dev/null) \[\033[00m\]# '

在我的Cygwin上,这比Wilbert's "fast_Git_PS1" answer更快 - 200毫秒与400毫秒相比,所以它可以减少你的一些迟钝。

它没有__git_ps1那么复杂 - 例如,当你进入.git目录等时,它不会改变提示,但是对于正常的日常使用它是足够好和快速的。

这是在Git 1.7.9(Cygwin,但它可以在任何平台上运行)上测试的。

答案 10 :(得分:5)

我在Git Bash和Git GUI中遇到了同样的问题。两个程序都运行良好,但随后它们随机减速到爬行,我无法弄清楚原因。

事实证明,这是Avast。 Avast已经导致各种程序(包括我编写的程序)发生奇怪的事情,所以我禁用了一秒钟,果然,Bash现在运行速度和Linux一样快。我刚刚将Git程序文件文件夹(C:\Program Files\Git)添加到Avast排除列表中,现在它的运行速度与在Linux上一样快。

是的,我知道防病毒软件不是原帖中的问题,但我会把它放在这里,以防它对某人有用。

答案 11 :(得分:4)

通过更改以下Git配置,您可能还会获得非常有效的性能提升:

git config --global status.submoduleSummary false

在Window 7 x64上运行简单git status命令时,我的计算机运行时间超过30秒。定义此选项后,命令立即生效。

如下页所述,激活Git自己的跟踪帮助我找到了问题的根源,这可能与您的安装有所不同: https://github.com/msysgit/msysgit/wiki/Diagnosing-why-Git-is-so-slow

答案 12 :(得分:3)

除了这些其他答案之外,我还通过使用并行子模块获取(从2016年初开始使用Git 2.8)加快了多个子模块的项目。

这可以使用public class LinkedHashmapBundler implements Bundler<LinkedHashMap> { @Override public void put(String s, LinkedHashMap val, Bundle bundle) { bundle.putSerializable(s, new Wrapper<>(val)); } @SuppressWarnings("unchecked") @Override public LinkedHashMap get(String s, Bundle bundle) { return ((Wrapper<LinkedHashMap>) bundle.getSerializable(s)).get(); } } // Use it like this @State(LinkedHashmapBundler.class) LinkedHasMap map 完成,并使用git fetch --recurse-submodules -j8设置,或者您拥有/想要使用多个核心。

答案 13 :(得分:2)

我在Windows 7 x64上运行Git for Windows(msysgit)作为受限用户帐户已经遇到了同样的问题。

从我在这里和其他地方读到的,共同的主题似乎是缺乏管理权限和/或UAC。由于UAC在我的系统上已关闭,因此它尝试在程序文件目录中编写/删除某些内容的解释对我来说是最有意义的。

无论如何,我通过安装带有zipinstaller的便携版Git 1.8解决了我的问题。请注意,我必须解压缩.7z分发文件并将其重新打包为ZIP文件,以便zipinstaller工作。我还必须手动将该目录添加到我的系统路径。

现在表现还不错。即使它安装在Program Files (x86)目录中,我没有作为受限用户的权限,但它似乎没有遇到同样的问题。

我将此归因于便携式版本在写入/删除文件的位置(可能是这种情况)或从1.7升级到1.8的位置更加保守。我不会试图确定哪一个是原因,足以说它现在好多了,包括Bash。

答案 14 :(得分:2)

如果您使用cmd中的Git,请尝试从Git Bash运行它。 在cmd中,git.exe实际上是一个包装器,每次启动它时都会设置正确的环境,然后才启动真正的git.exe。它可能需要两倍的时间才能完成您想要的任务。 Git Bash只在它启动时设置环境。

答案 15 :(得分:2)

在我的情况下,它实际上是Avast防病毒导致Git Bash甚至PowerShell变得非常慢。

我首先尝试禁用Avast 10分钟,看看它是否提高了速度,但确实如此。之后,我将整个Git Bash安装目录添加为Avast中的例外,用于读取,写入和执行。在我的情况下是C:\Program Files\Git\*

答案 16 :(得分:2)

综合答案:

  1. Wilbert's - PS1中包含哪些信息
  2. sinelaw's - (<branch_name>)(<sha>)
  3. # https://unix.stackexchange.com/questions/140610/using-variables-to-store-terminal-color-codes-for-ps1/140618#140618
    # https://unix.stackexchange.com/questions/124407/what-color-codes-can-i-use-in-my-ps1-prompt
    # \033 is the same as \e
    # 0;32 is the same as 32
    CYAN="$(echo -e "\e[1;36m")"
    GREEN="$(echo -e "\e[32m")"
    YELLOW="$(echo -e "\e[33m")"
    RESET="$(echo -e "\e[0m")"
    
    # https://stackoverflow.com/questions/4485059/git-bash-is-extremely-slow-in-windows-7-x64/19500237#19500237
    # https://stackoverflow.com/questions/4485059/git-bash-is-extremely-slow-in-windows-7-x64/13476961#13476961
    # https://stackoverflow.com/questions/39518124/check-if-directory-is-git-repository-without-having-to-cd-into-it/39518382#39518382
    fast_git_ps1 ()
    {
        git -C . rev-parse 2>/dev/null && echo " ($((git symbolic-ref --short -q HEAD || git rev-parse -q --short HEAD) 2> /dev/null))"
    }
    
    # you need \] at the end for colors
    # Don't set \[ at the beginning or ctrl+up for history will work strangely
    PS1='${GREEN}\u@\h ${YELLOW}\w${CYAN}$(fast_git_ps1)${RESET}\] $ '
    

    结果:

    frolowr@RWAMW36650 /c/projects/elm-math-kids (master) $

答案 17 :(得分:1)

上述任何内容都无法帮助我。在我的场景中,问题就是这样:

  • 任何ll命令都很慢(执行时间约为3秒)
  • 任何后续的ll命令都会立即执行,但仅限于距离上一个命令的45秒内。

当使用Process Monitor进行调试时,发现在每个命令之前都有DNS请求。

因此,一旦我禁用防火墙(在我的情况下是Comodo)并让命令执行,问题就消失了。当防火墙重新打开时,它不会返回。在最早的机会中,我将更新此响应,并提供有关阻止DNS请求的进程以及目标是什么的更多详细信息。

BR,G

答案 18 :(得分:0)

我遇到过类似的情况,我的问题与 Active Directory 和 vpn 相关。

这样干了半年才发现这个金子:http://bjg.io/guide/cygwin-ad/

您基本上只需要从 db/etc/nsswitch.conf 部分禁用 passwd 中的 group(您可以在您的 git 目录中找到它),因此该文件看起来像:

# Begin /etc/nsswitch.conf
passwd: files
group: files
db_enum: cache builtin
db_home: cygwin desc
db_shell: cygwin desc
db_gecos: cygwin desc
# End /etc/nsswitch.conf

然后更新您的本地密码和组设置一次:

$ mkpasswd -l -c > /etc/passwd
$ mkgroup -l -c > /etc/group

答案 19 :(得分:0)

正如许多人所说,这是由于stash是Windows上的shell脚本,但是自Git 2.18.0起,Windows安装程序可以选择具有更快(〜90%)内置功能的实验功能。在隐藏版本中- https://github.com/git-for-windows/build-extra/pull/203

答案 20 :(得分:0)

我的同事在Windows上遇到了Git问题(7)git status checkoutadd速度很快,但git commit需要很长时间。

我们仍在尝试找到这个的根本原因,但是将存储库克隆到新文件夹中解决了他的问题。

答案 21 :(得分:0)

在我的例子中,Git Bash快捷方式设置为Start in:%HOMEDRIVE%%HOMEPATH%(您可以通过右键单击Git Bash并选择属性来检查)。这是网络驱动器。

解决方案是指向%HOME%。如果你没有它,你可以在环境变量中进行设置,现在Git Bash应该是闪电般的。

答案 22 :(得分:0)

我也遇到了git PS1慢的问题,虽然很长一段时间我都认为这是一个数据库大小问题(大型存储库)并尝试了各种git gc技巧,并且正在寻找其他原因,就像你一样。但是,在我的情况下,问题是这一行:

function ps1_gitify
{
   status=$(git status 2>/dev/null )      # <--------------------
   if [[ $status =~ "fatal: Not a git repository" ]]
   then
       echo ""
   else
       echo "$(ps1_git_branch_name)  $(ps1_git_get_sha)"
  fi
}

为每个命令行状态行执行git status的速度很慢。哎哟。这是我手工写的东西。我在尝试

时看到这是一个问题
export PS1='$'
像这里的一个答案中提到的那样。命令行很快。

现在我正在使用它:

function we_are_in_git_work_tree
{
    git rev-parse --is-inside-work-tree &> /dev/null
}

function ps1_gitify
{
    if ! we_are_in_git_work_tree
    then
    ...

从Stack Overflow帖子 PS1 line with git current branch and colors ,它运行正常。再次拥有一个快速的Git命令行。