ChatGPT解决这个技术问题 Extra ChatGPT

Git Bash is extremely slow on Windows 7 x64

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

Not to discourage you but Cygwin is very slow on x64, you better try it on Windows XP 32bit.
On same system, it wasn't slow a half year ago. They must've changed something...
On virtually all machines here: Kaspersky AV massively slows down git and "disabling" Kaspersky is broken, avp.exe's still run after exiting it completely. Complete reinstall of kaspersky usually fixes the latter problem.

M
Mr Fooz

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/


Didn't help me, but helped the export PS1='$' mentioned below. So I know for me the problem is the terminal line.
Completely useless settings in 2017 (git 2.12) because all this stuff is enabled by default. But the git still works slowly like a shit.
Limiting files to 256 may cause some problems. And the first two options already enabled on new versions of git.
@sonyvizio What kind of problems?
Automatic gc has documented problems. I would turn that option off by git config --global gc.auto 0 and do gc manually. bugs.chromium.org/p/chromium/issues/detail?id=350413
C
Chris Dolan

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='$'

Problem is with $(__git_ps1) ... removing this makes everything superfast
For the uninitiated amongst us, what exactly does this command do? You say it's "temporary", how do we revert the command?
Also fixed my performance problems. To fix permanently, edit C:\Program Files (x86\Git\etc\profile and comment out the if-then-else where __git_ps1 is added to PS1.
In the current version 2.18.0 I canot find the __git_ps1 command in /etc/profile. Has it moved somewhere else?
It seems to have moved to C:\Program Files\Git\etc\profile.d\git-prompt.sh. I commented out __git_ps1 in that file and it went much faster (but lost branch info in prompt)
A
Alex Weitz

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 had the same issue. I changed HOME="$(cd "$HOME" ; pwd)" to HOME="$(cd "$USERPROFILE" ; pwd)", and now everything is blazingly fast. Thanks for the tip.
I was successful using a variation of this: in the profile, force $HOME to $USERPROFILE, removing the $HOMEDRIVE reference. Also on the properties of the Git Bash shortcut, set "Start In" to %USERPROFILE%
This fixed my issue for the most part, but with Git at least as of 2.7.2 I found that export in /etc/profile.d/env.sh instead of directly in the /etc/profile file.
Thanks so much, same problem for me, however I fixed it by creating an (user) environment variable called HOME, pointing to my desired home directory. If $HOME is not present, apparently git bash will default to %USERPROFILE%. After this, git bash is lightning fast.
The only option which worked for was the one @JHH described in the comments. Add a Windows user environment variable called HOME and define your desired home directory. (Control Panel -> System -> Advanced system settings -> Environment Variables)
S
Stefan van den Akker

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%

This worked. For everyone that has the network problem this is the real solution. You don't have to edit any config file just make HOME point where it should.
Defining Env User Var HOME as %USERPROFILE% didn't work. I defined SYSTEM VAR : HOME=C:\Users\myUserName
Worked for me! Thanks. I did something like @colin_froggatt but in User Environment variables instead, setting HOME=C:\Users\myUserName
Working with Windows 10 in 2020 the HOME variable was unset, giving it a default value recovered my previously horrible git performance on 2.28.
This worked for me. Thank you for your help! Windows 10
P
Peter Mortensen

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.


Great answer. However I've decided to redefine '__git_ps1()' in my ~/.bashrc, and just print empty string. It speeds up all the Bash commands.
I'm a git beginner, I'd like to know what the difference between this fast_git_ps1 and the original pretty complicated __git_ps1 is. I get the idea that this will work for most "normal" cases, but what's normal and where will this fail?
I am not aware of cases where it will fail. I did use the __git_ps1 before, but noticed the performance issues, so I tinkered around trying to make git do less work to extract the displayed information.
The original __git_ps1 includes status information, not just the branch name. For example, if you're in a detached head state, in the git dir, in a bare repo, in the middle of cherry picking or rebasing or merging... This will be faster, but there may be occasions where you would miss this extra info, especially as a Git beginner.
P
Peter Mortensen

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.


this only puts to light, yet again, idiotics and meandrous Microsoft solutions, to problems solved in Unix in a simple and elegant way in 1968. How much production effort, time and money has been wasted by Microsoft's bloat and lack of refactoring/flexiblity/audacity worldwide ?
I remember using git back in 68, it was glorious.
Haha a year before Linus came around @CharlieBrown
enabled by default in git 2.1 stackoverflow.com/a/24045966/4854931
L
Liam

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.


Reinstalling without restart did not work, uninstall-restart-install worked. Thanks! It would be nice to know why and how bash got so slow, though.
Re-installing with reboot in-between made no difference for me.
@RyanW I'm afraid I can't help beyond the solution above that worked for me, but since this issue doesn't seem to be permanently fixed yet, you might want to get in touch with msysgit's maintainers and see if they can figure out the cause of this issue.
Which bash config files did you wipe out exactly?
This is not the solution to the answer. When you uninstalled and reinstalled some config file might have changed, those changes are the answer. If you only say that reinstalling is the solution it is wrong. Other people may uninstall and reinstall and config files might be the same and that's why it won't work for everyone.
P
Peter Mortensen

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


The question talks about git bash.
You can run git bash as administrator; which may seem to indicate an UAC problem
Wow, huge speed improvement running git bash as administrator
I am not sure why this answer has just 6 up votes. I think this answer solved the problem completely. There is a huge speed improvement.
@vinoth10 Well, there's the issue with, you know, running as administrator. Which for many reasons is a bad idea, and for many corporate use cases is not an option at all. Solving a performance problem by elevating the user is a horrible solution.
P
Peter Mortensen

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


A
Andy

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


P
Peter Mortensen

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


You can also use the --short option to not print refs/heads/
@friederbluemle, which version of git are you using? Mine (1.7.9) doesn't offer --short for the symbolic-ref command.
Updated to not print errors when outside any git repo, and to work for detached HEADs
I'm using 1.8.4 (msysgit)
P
Peter Mortensen

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.


A
Alexander Trofimov

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

https://i.stack.imgur.com/FOFML.png

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


P
Peter Mortensen

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.


M
Michael

Combined answers:

Wilbert's - what info to include in PS1 sinelaw's - () or ()

# 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:

https://i.stack.imgur.com/t5kmm.png


did not make it any faster
@keinabel At this moment I would look at core.commitGraph=true from blogs.msdn.microsoft.com/devops/2018/06/25/… and other from blogs.msdn.microsoft.com/devops/tag/git
P
Peter Mortensen

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 think this answer should have more votes. I came here to post this same recommendation, but saw you already beat me to it lol.
P
Peter Mortensen

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.


Turning off UAC seems to solve the "big" part of the problem for us (multi-second delay). The ps1 hack did the rest.
Same I'm on SSD, 32GB RAM and quad core i7 and none of the other answers helped, disabled UAC, restart and git commands are INSTANT
P
Peter Mortensen

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


I want to confirm this tips. Exclude git from Avast really make thing faster. I see git status without waiting anymore. Win 7 x64
Antiviruses only interfere.
Thanks, that was definitely a quick win! Disabled avast for 10 minutes, noticed an instant change in git performance (i.e. return to normal execution times).
This solution worked for me. McAfee + Windows 10 Ent.
E
Eugene Pakhomov

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.


G
George

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

Any ll command was slow (was taking about 3 seconds to execute)

Any subsequent ll 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.

BR,G


ll being an alias for log? It seems odd that there would be DNS requests for that.
ll is an alias for ls -l. And it is still odd to trigger a DNS request anyway... Meanwhile I'm still waiting for this issue to appear again to add more details into the reply.
P
Peter Mortensen

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.


P
Peter Mortensen

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.


That helps with stash, but yours is the first post mentioning stash specifically. Does it affect other Git operations?
As far as I understand, no. Tthere are 2 experimental features in preview that allow to have stash and/or rebase using a native executable for better performance but with anything in preview there is always a small chance that there might be a small side-effect.
P.S. This feature went out of preview in v 2.19.1, therefore you do not get the option for it any more
r
r g

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

P
Peter Mortensen

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.


So your problem was caused by a script you had written? Maybe that script is not so likely to be the cause, for other users who search for the same problem...
Take a look at the OP question - he mentioned lots of things he had checked, and still it wasn't it. The same was with me. So here I added another thing to be checked when nothing helps. And it's not this specific script that I've written that is important, but a concept - look at your PS1.