powerlevel9k icon indicating copy to clipboard operation
powerlevel9k copied to clipboard

large git repo slows down prompt

Open jonathaw opened this issue 6 years ago • 12 comments

Hi all,

awesome theme! I have an issue with a VERY large repo, which slows down the prompt to an unusable speed. is there a way to flag specific repos to not be checked for git status etc.? I tried git config --add oh-my-zsh.hide-status 1 but it didn't change anything.

zsh version zsh 5.4.1 (x86_64-unknown-linux-gnu)

thanks!

jonathaw avatar Nov 29 '18 21:11 jonathaw

HI @jonathaw ! Yes, there is. But only on a segment level. So it will impact all repositories. But it is possible to enable or disable certain features on a repo basis with a bit of fiddling. Thinking about this, that could be a nice feature..

But first, could you go a bit into detail? I'd like to know:

  • Which version of P9K do you use (commit id or version)? Do you use a recent version of master or next? I am asking, because we did quite some performance improvements especially in the VCS segment. So it would be nice to know if it is still slow and why.
  • How long does it take to render the prompt on your machine? Could you do a time ( repeat 10; do; prompt_vcs "left" 1 false > /dev/null; done;) and post the output here? This renders the VCS prompt 10 times in a loop and outputs the timings (might run a while; takes about 20 seconds in the chromium repo on my laptop).
  • How big is your repo? I did some performance checks with the chromium repo (about 14gigs) and it takes about 8 seconds to render the prompt on my machine.
  • Is there anything special about your repo? Does it have a lot of submodules? Do you have a lot of untracked or modified files? Do you have a lot of stashes? Some of these have an impact on the performance.

Now the workaround, you asked for: The variable to modify is POWERLEVEL9K_VCS_GIT_HOOKS. It contains an array of all hooks that are executed every time a git repo is detected. Try to remove single elements from that array to see if that helps.

dritter avatar Nov 29 '18 21:11 dritter

Hi!

thanks for the quick reply.. the P9K git version I have is 2f4b15041fe31d85dc9ef705b818c3a0e6985da3, on master.

the output I get on my 30GB repo is:

+vi-git-untracked:local:8: not valid in this context: src/protocols/.ropeproject/config.py ( repeat 10; do; prompt_vcs "left" 1 false > /dev/null; done; ) 0.23s user 0.55s system 66% cpu 1.176 total +vi-git-untracked:local:8: not valid in this context: src/protocols/.ropeproject/config.py

the wierd thing is that I think it takes longer for the prompt to show up when I just run enter, than 10 times it does on your command.

I don't think the repo is special in anyway, it is just very large.

THANKS!

jonathaw avatar Dec 02 '18 16:12 jonathaw

Holy moly! That is huge!

It is indeed strange that the actual segment is slower than the prompt_vcs function. Not sure what is causing this. Tracing the VCS segment in the chromium repo, it hangs noticeable on two commands:

  • λ1 VCS_INFO_get_data_git:158 then git diff --no-ext-diff '--ignore-submodules=dirty' --quiet --exit-code; Checking for unstaged files
  • λ1 +vi-git-untracked:8 1 cmdsubst git ls-files --others --exclude-standard /Users/dr/test/chromium; Checking for untracked files.

And looking at your output vi-git-untracked:local:8 is this line in P9K. So, what version of ZSH are you running?

dritter avatar Dec 02 '18 22:12 dritter

I'm on zsh 5.4.1

jonathaw avatar Dec 03 '18 13:12 jonathaw

I tried removing all of the items from the POWERLEVEL9K_VCS_GIT_HOOKS list, but the problem persisted.

will it be possible to tell the plugin to ignore a specific repo?

jonathaw avatar Dec 07 '18 08:12 jonathaw

This should work today (you need to change specialConfigDir:

function p9kDirSpecificConfiguration(){
  local specialConfigDir="/Users/dr/test/chromium"
  if [[ "${PWD[0,${#specialConfigDir}]}" != "${specialConfigDir}" ]]; then
    if [[ -n "${OLD_P9K_VCS_GIT_HOOKS}" ]]; then
      # Restore possible old value
      P9K_VCS_GIT_HOOKS=(${OLD_P9K_VCS_GIT_HOOKS})
      unset OLD_P9K_VCS_GIT_HOOKS
      # Apply old settings
      __p9k_vcs_init
    fi

    return
  fi
  # Backup old config
  OLD_P9K_VCS_GIT_HOOKS=(${P9K_VCS_GIT_HOOKS})
  # New settings
  P9K_VCS_GIT_HOOKS=()
  # Apply new settings
  __p9k_vcs_init
}
chpwd_functions=(${chpwd_functions[@]} "p9kDirSpecificConfiguration")

You could easily adapt to disable the entire VCS segment if you want.

The function makes use of private functions of P9K, so it might break in the future. When I got some time, I'll write a hook to make dir specific configuration.

dritter avatar Dec 09 '18 19:12 dritter

I added your code to the zsh-theme file, and got these errors: p9kDirSpecificConfiguration:18: command not found: __p9k_vcs_init and +vi-git-untracked:local:8: not valid in this context: PATH/.ropeproject/config.py

maybe I put it in the wrong place?

thanks!

jonathaw avatar Dec 10 '18 08:12 jonathaw

Sorry, I should have gone more into detail. That snippet is supposed to go in your ~/.zshrc and is based on the current next branch. I placed it in my tests right before sourcing P9K. What it does is to disable all P9K specific VCS_INFO hooks (which doesn't help, as you already said), but you could do other settings (have a look into vcs.p9k::__p9k_vcs_init where we set a lot of VCS_INFO settings).

And about that not valid in this context error you get: It might be that we miss some parenthesis around that array, but I couldn't reproduce that error in ZSH 5.4.2 (and I assumed this is an error with some older ZSH version). Could you add a set of parenthesis around that array, and see if that helps?

dritter avatar Dec 10 '18 19:12 dritter

@jonathaw If you are still using Powerlevel9k, could you check if performance is improved with https://github.com/romkatv/powerlevel10k? It's a backward-compatible fork with identical behavior to Powerlevel9k but better performance.

Run these commands in a zsh shell with configured and enabled Powerlevel9k:

git clone https://github.com/romkatv/powerlevel10k.git /tmp/powerlevel10k
source /tmp/powerlevel10k/powerlevel10k.zsh-theme

Then check how it works in your huge git repo. You can also try this parameter (can be hot-changed right in the shell without touching configs):

# Don't scan for dirty files in git repos with more files in the index than this.
# Instead, show them with the "dirty" color (yellow by default) whether they
# are dirty or not. This makes git prompt much faster on huge repositories.
# The default is -1, which means that all repos are scanned for dirty files.
POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=10000

romkatv avatar Mar 08 '19 20:03 romkatv

... can be hot-changed right in the shell without touching configs

Sorry, this isn't true. It has to be defined before powerlevel10k.zsh-theme is sourced (and resourcing it for the second time won't help). This should work:

POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=10000 zsh

However, hopefully prompt will be fast enough even without this parameter.

romkatv avatar Mar 08 '19 20:03 romkatv

@romkatv this is awesome. I can see significant speed improvements, Thanks, man.

praval-singhal avatar Jul 22 '19 09:07 praval-singhal

I had this issue with a large repo too! Ended up using the 10k version for the improved speed. Thanks! :)

EzraLopez avatar Feb 13 '20 22:02 EzraLopez