git-aware-prompt
git-aware-prompt copied to clipboard
Prompt slows down noticeably
First of all thank you for this sweet tool. However, I'm having a problem where when using Git aware prompt my command prompt slows down noticeably. As in, when I press enter with no command entered it doesn't instantly show a new $ prompt. Something to note is that my repository is huge, so that might affect things. I believe the issue is with git diff-files --quiet 2>&1
. Here's some timing information:
wcauchois@fenris:~/repo (master)$ time git rev-parse --abbrev-ref HEAD 2> /dev/null
real 0m0.004s
user 0m0.002s
sys 0m0.002s
wcauchois@fenris:~/repo (master)$ time git diff-files --quiet 2>&1
real 0m0.051s
user 0m0.012s
sys 0m0.038s
As you can see, 0.05s is unacceptable. But this is probably because my repo is huge:
$ git bundle create /tmp/tmp.bundle --all && du -sh /tmp/tmp.bundle
Counting objects: 1123831, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (338881/338881), done.
Writing objects: 100% (1123831/1123831), 602.05 MiB | 52.58 MiB/s, done.
Total 1123831 (delta 659830), reused 1118676 (delta 655338)
602M /tmp/tmp.bundle
Also, I'm on Mac OSX 10.8.2.
Anyway, if you can think of a workaround that would be awesome, since I'd love to have this prompt.
Hey, the use of git diff-files
won't be surviving. As #7 points out there's some issues with it. Hopefully git status
which I'm planning to use instead is faster for your large repo :)
Would you mind running time git status --porcelain 2>/dev/null
to see how it compares to git diff-files
?
wcauchois@fenris:~/repo (master)$ time git status --porcelain 2>/dev/null
real 0m0.338s
user 0m0.198s
sys 0m0.139s
That's even worse than git diff-files
. Unfortunately I need to switch back to git status
again as diff-files
doesn't notice untracked files.
Have you garbage collected/optimized the repo with git gc
recently? I'm hoping this might offer some improvements.
I've just pushed some changes which switches find_git_dirty
back to using git status
again so it works properly.
As for your repo, I'm hoping running git gc
will help with the performance. But I'm open to ideas of other more performant means of getting the dirty state.
Any news about the performance after running git gc
? :)
You can add the --ignore-submodules, it decreased a time for 30% in my case. But obviously you will not see if they were changed.
In my experience git's store was not the bottleneck (git is so damn efficient!), but the storage device causes the slowdown, because git has to check through every folder in the project to see if there are any new or changed files for the dirty marker.
This is most noticeable when first entering a project folder with cd
. After that, prompts appear significantly more quickly because by then the machine has the file data in its disk cache.
My fork addresses this by aborting after a fixed timeout, so a prompt can be displayed without any stats, and leaves git status
running in the background. The user can happily execute commands, and when all the file data is finally cached the prompts will start displaying stats again.
The disadvantages with my approach is that your neat code becomes rather gnarly, and running and checking background processes adds a small overhead on every call. Also I cannot set the timeout too low, because even with data in the disk cache, git status
still takes some time to complete on large projects. (I am not interested in caching the output of git status
: I always want an up-to-date summary, or none at all.) So I feel this is only a partial solution, but one that works well enough for me.
(I am also unsure if this really addresses the OP's issue: he is worried about 50ms, whereas I am more worried about 5 seconds!)
Anyway thanks for the tool jimeh, it has made working with git much more relaxing for me!
btw, i ended up alleviating this for myself by just removing the dirty checking portion of the prompt.
that is, replace
PROMPT_COMMAND="find_git_branch; find_git_dirty; $PROMPT_COMMAND"
with
PROMPT_COMMAND="find_git_branch; $PROMPT_COMMAND"
since then i've been a loyal user :)
I'm gonna try to find some time to see if I can improve performance. Anyone know of any open source project I can clone that's causing these kinds of slow downs?
And @joeytwiddle, I like the idea of a timeout, I'll have a look at your fork :)
For testing, this project has a lot of files: https://github.com/torvalds/linux
But I only really experience the issue when first moving into a large repo. Once git status
has peeked at all the files, they are now available in the disk cache, and the slowdown goes away!
Therefore you might want to clear your disk caches before each test, to make the slowdown reliably reproducable.
+1 getting this issue too, repo has about 2000 files, only happens when first navigating to directory
Maybe #52 helps to solve this problem? Works for me, but haven't tested every possible case. But I'm confident that usage of "git status" should be possible to avoid.
I ran into this issue as well. The solution for me was to switch to git-prompt.sh.
This is what I end up doing to my .bashrc
source /usr/local/etc/bash_completion.d/git-prompt.sh
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_SHOWUPSTREAM="auto"
GIT_PS1_SHOWCOLORHINTS=true
export PS1="${debian_chroot:+($debian_chroot)}\[\033[0;32m\]\T\[\033[00m\]:\[\033[0;35m\]\w\[\033[0;36m\]\$(__git_ps1) \[\033[00m\]\$ "
It loads within ms
11:53:36:~ $ time source /usr/local/etc/bash_completion.d/git-prompt.sh
real 0m0.003s
user 0m0.002s
sys 0m0.001s