oh-my-zsh медленно, но только для определенного репозитория Git

102

Недавно я начал использовать Zsh, и это здорово. К сожалению, для проекта, который я считаю своим «основным», все идет медленно. Я имею в виду, что каждый раз, когда я запускаю команду ls, например, между моментом выполнения команды и моментом, когда я снова могу использовать терминал, возникает задержка в пять секунд.

Что может отличаться от этого репо, которое делает Zsh таким медленным? Я предполагаю, что это специфическая вещь для Zsh, потому что до того, как я начал использовать Zsh, проблем не было. Я попробовал сделать, git cleanно это не дало заметной разницы.

Я использую Mac OS X, если это важно.

Обновление:.zshenv оказывается, именно эта моя строка замедляла работу:

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

Если я прокомментирую эту строку, это займет от примерно 3 секунд до примерно 1 секунды. К сожалению, мне нужна эта строка, поскольку многие мои проекты используют RVM. Я не знаю, что мне теперь делать.

Обновление 2 : похоже, это особенная вещь о-о-о-о. Если я не загружаюсь ~/.oh-my-zsh/oh-my-zsh.sh, у меня нет проблем.

Джейсон Светт
источник
1
и если вы сейчас используете bash, он все еще медленный?
nneonneo 07
Отличный вопрос. Нет, на bash это быстро.
Джейсон Светт
Если вы переместите ~/.z*файлы в сторону, все равно будет медленно ?
user4815162342 07
Нет. Думаю, это что-то в одном из них.
Джейсон Светт
3
Если репо большой, вызов git st каждый раз может замедлить работу оболочки. Используйте эту опцию, чтобы выключить его. git config --add oh-my-zsh.hide-status 1
Сентил Кумар

Ответы:

172

Вы можете добавить это в свою конфигурацию git, и zsh больше не будет проверять статус

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

Объяснение

В lib / git.zsh есть две центральные функции git :

  • git_prompt_info()
  • parse_git_dirty()

У каждого метода есть переключатель конфигурации git, чтобы отключить его:

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

Некоторые темы создают свои собственные запросы git и иногда игнорируют эти флаги .

Паскалий
источник
4
Это решение все еще работает, просто попробовал это в моей папке проекта Symfony2. Может быть, папка vendor замедляет работу, как папка rake для приложений rails? zsh теперь работает быстро, и мне все равно не нужен плагин zsh для GIT. Благодарность!
mblaettermann
Это отлично решило мою проблему. Я все еще могу использовать хороший бизнес git-status в других репозиториях, но не в моем огромном репозитории исходного кода Firefox, где git it slow.
Лев Уфимцев
1
Пришлось использовать oh-my-zsh.hide-dirty. Возможно, это изменилось, а может моя тема (агностер) только уважает hide-dirty.
Бенджамин Аткин
1
Выполнение этого в глобальных настройках для vagrant virtualbox vms с --globalдействительно удобно (медленно в гостевой, быстро на хосте), как описано здесь: stackoverflow.com/a/40943155/1092815 <3
GabLeRoux
7
git config --add oh-my-zsh.hide-dirty 1было всем, что мне было нужно для моего медленного репо.
Джонатан Элмор
26

Oh_my_zsh кажется медленным для некоторых репозиториев, потому что он проверяет статус репо после каждой команды. Это поведение можно изменить в новой версии .oh_my_zsh. Просто раскомментируйте следующую строку в .zshrc:

DISABLE_UNTRACKED_FILES_DIRTY = "верно"

После этого перезапустите терминал или запустите следующее:

источник ~ / .zshrc

Пиюш Гоэла
источник
3
git config --add oh-my-zsh.hide-status 1ускоряет работу, но полностью удаляет zsh-статус VCS. Этот сохраняет его и все еще ускоряет.
nyxz
1
Я надеялся, что это сработает, но никакого эффекта даже после source ~ / .zshrc. git config --add oh-my-zsh.hide-dirty 1хотя работал на меня. git config --global --add oh-my-zsh.hide-dirty 1чтобы отключить это для всех репозиториев.
Джонатан Элмор
@JohnathanElmore @Peeyush, DISABLE_UNTRACKED_FILES_DIRTY="true"не делает то же самое, что и oh-my-zsh.hide-dirtyнастройка, хотя они похожи. Смотрите код здесь: github.com/ohmyzsh/ohmyzsh/blob/master/lib/git.zsh#L17 . Параметр DISABLE_UNTRACKED_FILES_DIRTYпросто добавляет --untracked-files=noк git statusкоманде флаг , тогда как oh-my-zsh.hide-dirty 1параметр полностью пропускает всю git statusкоманду. Я рекомендую предложение @ JohnathanElmore о глобальной настройке git config.
stwr667
13

Для меня это медленно на VirtualBox (гость), потому что я использую синхронизированную папку. Я все еще хочу, чтобы он был включен в OS X (хост), где он достаточно быстр. Вместо использования локальной настройки конфигурации, которая хранится в репозитории и изменяет ее как на гостевой, так и на хост-системе, я использую глобальную настройку конфигурации только для гостя :

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

Если я хочу это только для одного репо:

git config --add oh-my-zsh.hide-dirty 1
Бенджамин Аткин
источник
12

Это может быть тема, вызывающая git и rvm после каждой команды.

Для меня изменение ZSH_THEME="juanghurtadoto"на полностью ZSH_THEME="miloshadzic"удалило 2-секундную задержку после каждой команды.

Темы можно найти на https://github.com/robbyrussell/oh-my-zsh/wiki/themes

Джеймс ЭДжей
источник
Интересно. +1. Это более конкретно, чем мой ответ.
VonC
11

Есть несколько способов ускорить загрузку oh-my-zsh, как подробно описано в разделе « zsh запускается невероятно медленно », очистив раздел плагинов.

Например, в сообщении в блоге « Исправление медленной работы подсказок oh-my-zsh git-svn » эта parse_git_dirtyфункция упоминается как потенциальная проблема.

VonC
источник
Это помогло в том, что это привело меня к тому, что я начал комментировать материал, чтобы увидеть, что может ускорить загрузку. Я сузил проблему еще больше и обновил свой вопрос.
Джейсон Светт
Сообщение compinit немного улучшило для меня, но удаление parse_git_dirty действительно ускорило работу. Спасибо.
Raj
6

Я наконец-то понял. В моем проекте была rakeпапка с множеством файлов (например, 20 000). Я понятия не имею, для чего там была эта папка, но я удалил ее, Zsh больше не работает медленно, а мое приложение все еще работает.

Джейсон Светт
источник
Интересный отзыв (точнее, чем мой ответ) +1
VonC
5
И мне потребовалось всего 4 месяца, чтобы понять!
Джейсон Светт
Я так быстро нахожу! Я знаю некоторых, на что уходит несколько лет ;) meta.stackexchange.com/questions/36318/…
VonC
3

Если вас не интересуют другие программы управления версиями git, вы можете просто отключить все vcs_infos в своем *.zsh-themeи заменить их собственными gitкомандами.

Например, я настраиваю agnoster.zsh-theme:

  1. прокомментировать / удалить все строки, в которых есть vcs_info,
  2. редактировать код в prompt_git()функции из:

    ref="$vcs_info_msg_0_" к

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

По сути, я просто отключил все vcs_infoдействия и вместо этого использую собственную gitкоманду для проверки статусов репо. В результате я все еще могу видеть свое полезное приглашение git со скоростью, сравнимой с работой в каталоге, отличном от git. С этой небольшой модификацией мой zsh может работать в 4-5 раз быстрее в репозиториях git.

Примечание: используйте GNU grep, а не BSD grep.

Fronthem
источник
1

Ответы выше не решили мою проблему. В моем случае функция git_prompt_statusзанимает слишком много времени, чем другие. Поэтому я изменил ~ / .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
}

Хотя я использую ZSH_THEME_GIT_PROMPT_MODIFIED как знак неопределенности, вы можете выбрать любой статус, чтобы указать это, или реализовать гораздо более быструю git_prompt_statusфункцию в вашем случае.

Xavier.S
источник
0

Для тех, кто использует тему космического корабля, добавьте это в .zshrc:

SPACESHIP_GIT_STATUS_SHOW="false"

работал у меня. Очевидно, вы потеряете статус git в командной строке терминала.

Параметры git для этой темы можно найти здесь

Harpal
источник