开发者

Git Bash is extremely slow on Windows 7 x64

开发者 https://www.devze.com 2023-01-31 13:53 出处:网络
I\'ve been using Git on both Windows and Ubuntu during the development of a small project, frequently flipping back and forth between the two. The issue is that Git Ba开发者_开发百科sh consistently be

I've been using Git on both Windows and Ubuntu during the development of a small project, frequently flipping back and forth between the two. The issue is that Git Ba开发者_开发百科sh consistently becomes slow.

When I say slow, I mean that running cd takes anywhere from 8-25 seconds, running git commands take from 5-20 seconds, and ls can take up to 30 seconds sometimes. Needless to say, this is not fun, not to mention unproductive. I know Git is slower on Windows, but this is ridiculous.

The one solution which has worked--temporarily--for me has been to disable my network connection (as suggested in this answer), start Git Bash, and then reconnect. Sometimes it continues to run quickly for days after doing that, but the performance always degrades eventually. I've trawled through the msysgit discussion group, Stack Overflow, msysgit issue list, etc. on and off for weeks, but I haven't been able to turn up solutions which work.

So far, I've tried:

  • Adding Git & project folders to the virus scanner's exclusion list
  • Disabling my virus scanner completely (Kaspersky IS 2011)
  • Ensuring that Outlook is not running (Outlook 2007)
  • Shutting down all other applications
  • Running Git Bash as administrator
  • Disabling network connection, starting Git Bash, and keeping connection disabled
  • Disabling network connection, starting Git Bash, re-enabling connection (works only occasionally)
  • Running git gc
  • And combinations of the above

I did read that a couple of people had success disabling Bash completion, but ideally I'd like to keep that active. The version of msysgit is 1.7.3.1-preview20101002 & the OS is Windows 7 x64. Running the same things on Linux is, predictably, lightning fast. I would use Linux exclusively, but I need to run stuff in Windows, too (certain applications, testing, etc.).

Has anyone encountered a similar issue? If so, what was the underlying problem and what was the solution (if any)?

This extends beyond just the Git repositories, but just for reference, the repositories I've been using Git with have been pretty small: ~4-50 files maximum.


You can significantly speed up Git on Windows by running three commands to set some config options:

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

Notes:

  • core.preloadindex does filesystem operations in parallel to hide latency (update: enabled by default in Git 2.1)

  • core.fscache fixes UAC issues so you don't need to run Git as administrator (update: enabled by default in Git for Windows 2.8)

  • gc.auto minimizes the number of files in .git/


Do you have Git information showing in your Bash prompt? If so, maybe you're inadvertently doing way too much work on every command. To test this theory try the following temporary change in Bash:

export PS1='$'


My Windows home directory is on the network, and I suspected that Git Bash commands were looking there first. Sure enough, when I looked at $PATH, it listed /h/bin first, where /h is a share on a Windows file server, even though /h/bin doesn't exist.
I edited /etc/profile and commented out the export command that puts it first in $PATH:

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

This made my commands run much faster, probably because Git Bash is no longer looking across the network for the executables. My /etc/profile was c:\Program Files (x86)\Git\etc\profile.


I found the network drive was the performance problem. HOME was pointing to a slow network share. I could not override HOMEDRIVE but that is not a problem from what I have seen.

Set the environment variable by right clicking your computer on the desktop --> properties --> Advanced system settings --> Environment Variables Add to User variables section

HOME=%USERPROFILE%


In an extension to Chris Dolan's answer, I used the following alternative PS1 setting. Simply add the code fragment to your ~/.profile (on 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\]
$ '

This retains the benefit of a colored shell and display of the current branch name (if in a Git repository), but it is significantly faster on my machine, from ~0.75 s to 0.1 s.

This is based on this blog post.


While your problem might be network-based, I've personally sped up my local git status calls tenfold (7+ seconds down to 700 ms) by doing two modifications. This is on a 700 MB repository with 21,000 files and excessive numbers of large binary files.

One is enabling parallel index preloads. From a command prompt:

git config core.preloadindex true
This changed time git status from 7 seconds to 2.5 seconds.

Update!

The following is no longer necessary. A patch has fixed this as of mysysgit 1.9.4
https://github.com/msysgit/git/commit/64d63240762df22e92b287b145d75a0d68a66988
However, you must enable the fix by typing
git config core.fscache true

I also disabled the UAC and the "luafv" driver (reboot required). This disables a driver in Windows Vista, 7 and 8 that redirects programs trying to write to system locations and instead redirects those accesses to a user directory.

To see a discussion on how this affects Git performance, read here: https://code.google.com/p/msysgit/issues/detail?id=320

To disable this driver, in regedit, change the "start" key at HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/luafv to 4 to disable the driver. Then, put UAC to its lowest setting, "never notify".

If the disabling of this driver makes you wary (it should), an alternative is running on a drive (or partition) different than your system partition. Apparently the driver only runs on file access on the system partition. I have a second hard drive and see identical results when run with this registry modification on my C drive as I do without it on the D drive.

This change takes time git status from 2.5 seconds down to 0.7 seconds.

You also might want to follow https://github.com/msysgit/git/pull/94 and https://github.com/git/git/commit/d637d1b9a8fb765a8542e69bd2e04b3e229f663b to check out what additional work is underway for speed issues in Windows.


It appears that completely uninstalling Git, restarting (the classic Windows cure), and reinstalling Git was the cure. I also wiped out all bash config files which were left over (they were manually created). Everything is fast again.

If for some reason reinstalling isn't possible (or desirable), then I would definitely try changing the PS1 variable referenced in Chris Dolan's answer; it resulted in significant speedups in certain operations.


I solved my slow Git problem on Windows 7 x64 by starting cmd.exe with "Run as administrator".


You might also gain a very subsquent performance boost by changing the following Git configuration:

git config --global status.submoduleSummary false

When running the simple git status command on Window 7 x64, it took my computer more than 30 seconds to run. After this option was defined, the command is immediate.

Activating Git's own tracing as explained in the following page helped me found the origin of the problem, which might differ in your installation: https://github.com/msysgit/msysgit/wiki/Diagnosing-why-Git-is-so-slow


I saw a decent improvement by setting core.preloadindex to true as recommended here.


As noted in Chris Dolan's and Wilbert's answers, PS1 slows you down.

Rather than completely disabling (as suggested by Dolan) or using the script offered by Wilbert, I use a "dumb PS1" that is much faster.

It uses (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\]# '

On my Cygwin, this is faster than Wilbert's "fast_Git_PS1" answer - 200 ms vs. 400 ms, so it shaves off a bit of your prompt sluggishness.

It isn't as sophisticated as __git_ps1 - for example it doesn't change the prompt when you cd into the .git directory, etc. but for normal everyday use it's good enough and fast.

This was tested on Git 1.7.9 (Cygwin, but it should work on any platform).


In addition to these other answers, I've sped up projects with multiple submodules by using parallel submodule fetching (since Git 2.8 in early 2016).

This can be done with git fetch --recurse-submodules -j8 and set with git config --global submodule.fetchJobs 8, or however many cores you have/want to use.


Only turning off AMD Radeon Graphics (or Intel Graphics) in Device Manager helped me.

Git Bash is extremely slow on Windows 7 x64

I found the answer here: https://superuser.com/questions/1160349/git-is-extremely-slow-on-windows#=


I was having the same problem, in both Git Bash and Git GUI. Both programs use to run nicely, but then they randomly slowed down to a crawl, and I couldn't figure out why.

As it turns out, it was Avast. Avast has caused odd things to happen to various programs (including programs I write), so I disabled it for a second, and sure enough, Bash now runs as fast as it does on Linux. I just added the Git program files folder (C:\Program Files\Git) to the Avast exclusion list, and now it runs as fast as it does on Linux.

And yes, I realize the antivirus software was not the issue in the original post, but I'll just put this here in case it's useful to someone.


Combined answers:

  1. Wilbert's - what info to include in PS1
  2. sinelaw's - (<branch_name>) or (<sha>)
# 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}\] $ '

Result:

Git Bash is extremely slow on Windows 7 x64


In my case, the Git Bash shortcut was set to Start in:%HOMEDRIVE%%HOMEPATH% (you can check this by right clicking Git Bash and selecting properties). This was the network drive.

The solution is to make it point to %HOME%. If you do not have it, you can set it up in the environment variables and now Git Bash should be lightning fast.


I've encountered the same problem running Git for Windows (msysgit) on Windows 7 x64 as a limited user account for quite some time.

From what I've read here and other places, the common theme seems to be the lack of administrative privileges and/or UAC. Since UAC is off on my system, the explanation that it is trying to write/delete something in the program files directory makes the most sense to me.

In any case, I've resolved my problem by installing the portable version of Git 1.8 with zipinstaller. Note that I had to unpack the .7z distribution file and repack it as a ZIP file in order for zipinstaller to work. I also had to manually add that directory to my system path.

The performance is fine now. Even though it is installed in the Program Files (x86) directory, which I don't have permissions for as a limited user, it doesn't seem to suffer from the same problem.

I ascribe this either to the fact that the portable version is a bit more conservative in where it writes/deletes files, which is probably the case, or to the upgrade from 1.7 to 1.8. I'm not going to try to pin down which one is the reason, suffice to say it works much better now, including Bash.


In my case, it actually was Avast antivirus leading to Git Bash and even PowerShell becoming really slow.

I first tried disabling Avast for 10 minutes to see if it improved the speed and it did. Afterwards, I added the entire Git Bash installation directory as an exception in Avast, for Read, Write and Execute. In my case that was C:\Program Files\Git\*.


If you use Git from cmd, try running it from Git Bash. In cmd, git.exe is actually a wrapper that sets up the correct environment every time you start it, and only then launches the real git.exe. It can take up to twice as much time as it's required to just do what you want. And Git Bash sets up the environment only when it starts.


A co-worker of mine had troubles with Git on Windows (7) git status checkout and add were fast, but git commit took ages.

We are still trying to find the root cause of this, but cloning the repository into a new folder fixed his problem.


As many said, this is due to stash being a shell script on Windows, but since Git 2.18.0 the Windows installer has an option for an experimental feature of a much faster (~90%) built-in version of stash - https://github.com/git-for-windows/build-extra/pull/203.


I've had similar situation and my problem was related to Active Directory and sitting behind vpn.

Found this gold after working like that for half a year: http://bjg.io/guide/cygwin-ad/

All you basicaly need is to disable db in /etc/nsswitch.conf (you can find it in your git directory) from passwd and group section, so the file looks like:

# 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

and then update your local password and group settings once:

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


Nothing of the above was able to help me. In my scenario the issue was showing itself like this:

  • Any ls -l command was slow (was taking about 3 seconds to execute)
  • Any subsequent ls -l command was executed instantly, but only if within 45 seconds from the previous ls command.

When it came to debugging with Process Monitor it was found that before every command there was a DNS request.

So as soon as I disabled my firewall (Comodo in my case) and let the command execute the issue is gone. And it is not returning back when the firewall was switched back on. With the earliest opportunity I'll update this response with more details about what process was doing a blocking DNS request and what was the target.


I also had issue with git PS1 slowness, although for a long time I was thinking it's a database size problem (big repository) and was trying various git gc tricks, and were looking for other reasons, just like you. However, in my case, the problem was this line:

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
}

Doing the git status for every command line status line was slow. Ouch. It was something I wrote by hand. I saw that was a problem when I tried the

export PS1='$'

like mentioned in one answer here. The command line was lightning fast.

Now I'm using this:

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
    ...

From the Stack Overflow post PS1 line with git current branch and colors and it works fine. Again have a fast Git command line.

0

精彩评论

暂无评论...
验证码 换一张
取 消