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

Відмінне запитання. Ні, це швидко на баш.
Jason Swett,

Це все ще повільно, якщо ви переміщуєте ~/.z*файли з дороги?
користувач4815162342

Ні. Тож, мабуть, це щось у тому.
Джейсон Світт,

3
Якщо репо велике, виклик git st кожного разу може сповільнити оболонку. Використовуйте цей параметр, щоб вимкнути його. git config --add oh-my-zsh.hide-status 1
Senthil Kumar

Відповіді:


173

Ви можете додати це до конфігурації 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 config, щоб його вимкнути:

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

Деякі теми створюють власні запити git, а іноді ігнорують ці прапори .


4
Це рішення все ще працює, просто спробував це в моїй папці проекту Symfony2. Можливо, папка постачальника робить роботу повільною, як папка rake для програм рейок? zsh зараз швидкий, і мені все одно не потрібен плагін GIT zsh. Дякую!
mblaettermann

Це прекрасно вирішило мою проблему. Я все ще можу використовувати приємний git-статус бізнесу в інших репозиторіях, але не у своєму величезному репо-файлі вихідного коду Firefox, де git це повільно.
Лео Уфімцев

1
Мені довелося скористатися oh-my-zsh.hide-dirty. Можливо, це змінилося, або, можливо, моя тема (agnoster) лише поважає hide-dirty.
Бенджамін Аткін

1
Робити це в глобальних налаштуваннях для безпритульних 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
Я сподівався, що це зробить трюк, але ніякого ефекту навіть після джерела ~ / .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функцію як про потенційну проблему.


Ці речі допомогли в тому, що це змусило мене почати коментувати речі, щоб побачити, що може зробити речі швидшими. Я ще більше звузив проблему та оновив своє запитання.
Jason Swett,

Допис у компілітеті покращив для мене невелику кількість, але видалення parse_git_dirty дійсно пришвидшило. Дякую.
Радж

6

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


Цікавий відгук (точніший за мою відповідь) +1
VonC

5
І мені знадобилося всього 4 місяці!
Jason Swett

Я вважаю це швидко! Я знаю, що займає кілька років ;) 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 із такою швидкістю, як робота в каталозі non-git. За допомогою цієї невеликої модифікації мій zsh може працювати в 4-5 разів швидше в межах git repos.

Примітка: використовуйте GNU grep, а не BSD grep.


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функцію у вашому випадку.


0

Для тих, хто використовує тему космічного корабля, додайте це до .zshrc:

SPACESHIP_GIT_STATUS_SHOW="false"

працював у мене. Очевидно, ви втратите статус git у підказці терміналу.

Параметри git для цієї теми можна знайти тут

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.