Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prompt slows down noticeably #9

Open
wcauchois opened this issue Apr 25, 2013 · 14 comments
Open

Prompt slows down noticeably #9

wcauchois opened this issue Apr 25, 2013 · 14 comments

Comments

@wcauchois
Copy link

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.

@jimeh
Copy link
Owner

jimeh commented Apr 25, 2013

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

@jimeh
Copy link
Owner

jimeh commented Apr 25, 2013

Would you mind running time git status --porcelain 2>/dev/null to see how it compares to git diff-files?

@wcauchois
Copy link
Author

wcauchois@fenris:~/repo (master)$ time git status --porcelain 2>/dev/null

real    0m0.338s
user    0m0.198s
sys 0m0.139s

@jimeh
Copy link
Owner

jimeh commented Apr 25, 2013

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.

@jimeh
Copy link
Owner

jimeh commented Apr 25, 2013

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.

@jimeh
Copy link
Owner

jimeh commented Apr 28, 2013

Any news about the performance after running git gc? :)

@Kostanos
Copy link

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.

@joeytwiddle joeytwiddle mentioned this issue Sep 27, 2015
@joeytwiddle
Copy link

joeytwiddle commented Sep 27, 2015

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!

@wcauchois
Copy link
Author

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

@jimeh
Copy link
Owner

jimeh commented Oct 16, 2015

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

@joeytwiddle
Copy link

joeytwiddle commented Oct 20, 2015

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.

@emptyflash
Copy link

+1 getting this issue too, repo has about 2000 files, only happens when first navigating to directory

@joeytwiddle joeytwiddle mentioned this issue Apr 5, 2016
12 tasks
@simonsthings
Copy link

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.

oizik pushed a commit to oizik/git-aware-prompt that referenced this issue Nov 21, 2017
@ssgao
Copy link

ssgao commented Mar 20, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants