简体   繁体   English

oh-my-zsh 很慢,但仅适用于某些 Git 存储库

[英]oh-my-zsh slow, but only for certain Git repo

I recently started using Zsh and it's awesome.我最近开始使用 Zsh,它很棒。 Unfortunately, for the project I consider my "main" project, everything is slow.不幸的是,对于我认为是我的“主要”项目的项目,一切都很慢。 What I mean is that every time I run a command - ls , for example - there's about a five-second delay between the time the command is executed and the time I can use the terminal again.我的意思是,每次我运行命令时 - 例如 - ls执行命令和我可以再次使用终端的时间之间大约有五秒钟的延迟。

What could be different about this one repo that makes Zsh so slow?这个让 Zsh 如此缓慢的 repo 有什么不同? I assume it's a Zsh-specific thing because there was no problem before I started using Zsh.我认为这是 Zsh 特定的东西,因为在我开始使用 Zsh 之前没有问题。 I tried doing a git clean but it didn't make any noticeable difference.我试着做一个git clean但它没有任何明显的区别。

I'm on Mac OS X if that matters.如果这很重要,我在 Mac OS X 上。

Update: Turns out this line of my .zshenv is what was making it slow:更新:原来我的这行.zshenv是让它变慢的原因:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function

If I comment that line, it goes from taking about 3 seconds to taking about 1 second.如果我评论该行,它会从大约 3 秒变为大约 1 秒。 Unfortunately, I need that line, since many of my projects use RVM.不幸的是,我需要那条线,因为我的许多项目都使用 RVM。 I don't know what to do now.我现在不知道该怎么办。

Update 2 : this seems to be specifically an oh-my-zsh thing.更新 2 :这似乎是一个 oh-my-zsh 的事情。 If I don't load ~/.oh-my-zsh/oh-my-zsh.sh , I don't have a problem.如果我不加载~/.oh-my-zsh/oh-my-zsh.sh ,我没有问题。

You can add this to your git config and zsh won't check the status anymore您可以将此添加到您的 git 配置中,zsh 将不再检查状态

git config --add oh-my-zsh.hide-status 1
git config --add oh-my-zsh.hide-dirty 1

Explanation解释

There are two central git functions in in lib/git.zsh : lib/git.zsh 中有两个核心的 git 函数:

  • git_prompt_info()
  • parse_git_dirty()

Each Method has a git config switch to disable it:每个方法都有一个 git config 开关来禁用它:

  • oh-my-zsh.hide-status
  • oh-my-zsh.hide-dirty

Some themes create their own git queries and sometimes ignore these flags .一些主题创建自己的 git 查询,有时会忽略这些标志

Oh_my_zsh seems to be slow for some repos because it checks the status of the repo after each command. Oh_my_zsh 对于某些 repos 似乎很慢,因为它在每个命令之后检查 repo 的状态。 This behaviour can be overridden in the new version of .oh_my_zsh .这种行为可以在 .oh_my_zsh 的新版本中被覆盖。 Just Uncomment the following line in .zshrc:只需取消注释 .zshrc 中的以下行:

DISABLE_UNTRACKED_FILES_DIRTY="true" DISABLE_UNTRACKED_FILES_DIRTY="真"

After this, restart your terminal or run the following:之后,重新启动终端或运行以下命令:

source ~/.zshrc源 ~/.zshrc

It could be the theme calling git and rvm stuff after every command.它可能是在每个命令之后调用 git 和 rvm 东西的主题。

For me, changing ZSH_THEME="juanghurtadoto" to ZSH_THEME="miloshadzic" removed the 2 second delay after every command completely.对我来说,将ZSH_THEME="juanghurtadoto"更改为ZSH_THEME="miloshadzic"消除了每个命令后的 2 秒延迟。

Themes can be found at https://github.com/robbyrussell/oh-my-zsh/wiki/themes主题可以在https://github.com/robbyrussell/oh-my-zsh/wiki/themes找到

For me it's slow on VirtualBox (the guest) because I'm using a synced folder.对我来说,VirtualBox(来宾)很慢,因为我使用的是同步文件夹。 I still want it enabled on OS X (the host) where it's fast enough.我仍然希望它在足够快的 OS X(主机)上启用。 Instead of using a local config setting which is stored with the repo and would change it both on the guest and host, I use a global config setting only on the guest :我没有使用存储在 repo 中的本地配置设置,并且会在来宾和主机上更改它,而是仅在来宾上使用全局配置设置

git config --global --add oh-my-zsh.hide-dirty 1

If I want it just for a single repo:如果我只想要一个回购:

git config --add oh-my-zsh.hide-dirty 1

There are various way to speed up an oh-my-zsh , as detailed in " zsh starts incredibly slowly ", cleaning up the plugin section.有多种方法可以加速oh-my-zsh ,如“ zsh 启动非常缓慢”中所述,清理插件部分。

For instance, the blog post " Fix for oh-my-zsh git-svn prompt slowness " mentions the parse_git_dirty function as a potential issue.例如,博客文章“ 修复 oh-my-zsh git-svn 提示缓慢”提到parse_git_dirty函数是一个潜在问题。

I finally figured it out.我终于弄明白了。 My project had a rake folder with a ton of files (like 20,000).我的项目有一个包含大量文件(如 20,000 个)的rake文件夹。 I have no idea what that folder was there for, but I deleted it, Zsh is no longer slow, and my app still seems to work.我不知道那个文件夹是做什么用的,但我删除了它,Zsh 不再慢,我的应用程序似乎仍然有效。

If you don't care about another version control programs but git , you can just disable all vcs_info s in your *.zsh-theme and replace them with native git commands.如果您不关心其他版本控制程序而是git ,您可以禁用*.zsh-theme所有vcs_info并用本机git命令替换它们。

For example I tweak my agnoster.zsh-theme by:例如,我通过以下方式调整我的agnoster.zsh-theme

  1. comment/remove all lines that have vcs_info ,注释/删除所有具有vcs_info
  2. edit code in prompt_git() function from:编辑prompt_git()函数中的代码:

    ref="$vcs_info_msg_0_" to ref="$vcs_info_msg_0_"

    ref="$(git branch 2>/dev/null | grep -Po '(?<=\\* ).*$')"

So, basically, I just disabled all vcs_info actions, and instead use a native git command for checking statuses of the repo.所以,基本上,我只是禁用了所有vcs_info操作,而是使用本机git命令来检查存储库的状态。 As a result, I still can see my useful git prompt with a speed as fast as working in a non-git directory.结果,我仍然可以以与在非 git 目录中工作一样快的速度看到我有用的 git 提示。 With this small modification, my zsh can work 4-5x faster within git repos.通过这个小小的修改,我的 zsh 在 git repos 中的运行速度可以提高 4-5 倍。

Note: use GNU grep not BSD grep.注意:使用 GNU grep 而不是 BSD grep。

Answers above didn't solve my problem.上面的答案没有解决我的问题。 In my case, the function git_prompt_status takes too much time than others.就我而言,函数git_prompt_status比其他函数花费太多时间。 So I modified ~/.oh-my-zsh/lib/git.zsh, replacing git_prompt_status function with my early return version:所以我修改了 ~/.oh-my-zsh/lib/git.zsh,用我早期的返回版本替换了git_prompt_status函数:

function git_prompt_status() {
  STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
  echo $STATUS
  return

  local INDEX STATUS
  INDEX=$(command git status --porcelain -b 2> /dev/null)
  STATUS=""
  if $(echo "$INDEX" | command grep -E '^\?\? ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_UNTRACKED$STATUS"
  fi
  if $(echo "$INDEX" | grep '^A  ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS"
  elif $(echo "$INDEX" | grep '^M  ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS"
  elif $(echo "$INDEX" | grep '^MM ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS"
  fi
  if $(echo "$INDEX" | grep '^ M ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
  elif $(echo "$INDEX" | grep '^AM ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
  elif $(echo "$INDEX" | grep '^MM ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
  elif $(echo "$INDEX" | grep '^ T ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
  fi
  if $(echo "$INDEX" | grep '^R  ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_RENAMED$STATUS"
  fi
  if $(echo "$INDEX" | grep '^ D ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
  elif $(echo "$INDEX" | grep '^D  ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
  elif $(echo "$INDEX" | grep '^AD ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
  fi
  if $(command git rev-parse --verify refs/stash >/dev/null 2>&1); then
    STATUS="$ZSH_THEME_GIT_PROMPT_STASHED$STATUS"
  fi
  if $(echo "$INDEX" | grep '^UU ' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_UNMERGED$STATUS"
  fi
  if $(echo "$INDEX" | grep '^## [^ ]\+ .*ahead' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_AHEAD$STATUS"
  fi
  if $(echo "$INDEX" | grep '^## [^ ]\+ .*behind' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_BEHIND$STATUS"
  fi
  if $(echo "$INDEX" | grep '^## [^ ]\+ .*diverged' &> /dev/null); then
    STATUS="$ZSH_THEME_GIT_PROMPT_DIVERGED$STATUS"
  fi
  echo $STATUS
}

While I use ZSH_THEME_GIT_PROMPT_MODIFIED as a mark of undetermined, you may choose any status you like to indicate that or implement a much faster git_prompt_status function in your case.虽然我使用 ZSH_THEME_GIT_PROMPT_MODIFIED 作为未确定的标记,但您可以选择任何您喜欢的状态来表示或在您的情况下实现更快的git_prompt_status函数。

For anyone using the spaceship theme add this to .zshrc :对于使用宇宙飞船主题的任何人,请将其添加到.zshrc

SPACESHIP_GIT_STATUS_SHOW="false"

worked for me.为我工作。 Obviously, you will lose the git status in your terminal prompt.显然,您将在终端提示中丢失 git 状态。

The git options for this theme can be found here可以在此处找到此主题的 git 选项

Edits编辑

Updated link to git options is here git 选项的更新链接在这里

For others coming to this question looking to improve their zsh git latency, the following reduced my latency from 40ms to 4ms :对于寻求改善 zsh git 延迟的其他人来说,以下将我的延迟从40ms减少到4ms

  1. Compile and install an optimized git-branch-name command:编译并安装优化的git-branch-name命令:

     git clone https://github.com/notfed/git-branch-name cd git-branch-name make sudo install git-branch-name /usr/local/bin/
  2. Add this to your ~/.zshrc :将此添加到您的~/.zshrc

     function git_prompt_info() { ref=$(git-branch-name -q -h 12 -b 64) || return echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref}${ZSH_THEME_GIT_PROMPT_CLEAN}${ZSH_THEME_GIT_PROMPT_SUFFIX}" }

(The -h and -b flags control truncation length for branch names and hashes, respectively.) -h-b标志分别控制分支名称和散列的截断长度。)

With this, I can hold enter and not experience any lag.有了这个,我可以保持进入并且不会遇到任何滞后。

I had the same issue.我遇到过同样的问题。 I ran the following command to get a list of all the themes that are not using hard-coded git plugin:我运行以下命令以获取未使用硬编码 git 插件的所有主题的列表:

grep --files-without-match "git" ~/.oh-my-zsh/themes/*

The prompts became much faster, but I didn't like any of those themes.提示变得更快了,但我不喜欢这些主题中的任何一个。

I ended up using powerline10k, which can be configured to look pretty nice and doesn't have the speed issue.我最终使用了 powerline10k,它可以配置为看起来非常漂亮并且没有速度问题。

I wanted to keep my git status, so all the other answers weren't helpful to me.我想保持我的 git 状态,所以所有其他答案对我都没有帮助。

The thing that really helped me is running this command in the git repository that was slow for me:真正帮助我的是在 git 存储库中运行这个命令,这对我来说很慢:

git gc

It stands for Garbage Collect and is fully explained here , but basically:它代表垃圾收集并在此处进行了充分解释,但基本上:

[It] Runs a number of housekeeping tasks within the current repository, such as compressing file revisions (to reduce disk space and increase performance) [It] 在当前存储库中运行许多内务管理任务,例如压缩文件修订(以减少磁盘空间并提高性能)

After running this command, there was no loading anymore.运行此命令后,不再加载。 Everything was instant again.一切又是瞬间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM