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.
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='$'
$(__git_ps1)
... removing this makes everything superfast
C:\Program Files (x86\Git\etc\profile
and comment out the if-then-else where __git_ps1
is added to 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
.
HOME="$(cd "$HOME" ; pwd)"
to HOME="$(cd "$USERPROFILE" ; pwd)"
, and now everything is blazingly fast. Thanks for the tip.
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.
__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.
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
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).
--short
option to not print refs/heads/
--short
for the symbolic-ref
command.
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.
https://i.stack.imgur.com/FOFML.png
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:
Wilbert's - what info to include in PS1 sinelaw's - (
# 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
core.commitGraph=true
from blogs.msdn.microsoft.com/devops/2018/06/25/… and other from blogs.msdn.microsoft.com/devops/tag/git
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.
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.
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.
stash
, but yours is the first post mentioning stash
specifically. Does it affect other Git operations?
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.
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
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.
Success story sharing
git config --global gc.auto 0
and do gc manually. bugs.chromium.org/p/chromium/issues/detail?id=350413