oh-my-zsh wolno, ale tylko dla niektórych repozytoriów Git

105

Niedawno zacząłem używać Zsh i jest niesamowity. Niestety, w przypadku projektu, który uważam za swój „główny”, wszystko przebiega powoli. Chodzi mi o to, że za każdym razem, gdy wykonuję polecenie - lsna przykład - występuje około pięciosekundowe opóźnienie między momentem wykonania polecenia a momentem, w którym mogę ponownie użyć terminala.

Co może być innego w tym jednym repozytorium, które sprawia, że ​​Zsh jest tak wolne? Zakładam, że jest to rzecz specyficzna dla Zsh, ponieważ nie było problemu, zanim zacząłem używać Zsh. Próbowałem zrobić, git cleanale nie zrobiło to żadnej zauważalnej różnicy.

Jestem na Mac OS X, jeśli to ma znaczenie.

Aktualizacja: Okazuje się, że ten wiersz mojego .zshenvpowodu spowalniał:

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

Jeśli skomentuję tę linię, zajmie to od około 3 sekund do około 1 sekundy. Niestety potrzebuję tej linii, ponieważ wiele moich projektów korzysta z RVM. Nie wiem, co mam teraz zrobić.

Aktualizacja 2 : wydaje się, że jest to sprawa oh-my-zsh. Jeśli nie ładuję ~/.oh-my-zsh/oh-my-zsh.sh, nie mam problemu.

Jason Swett
źródło
1
a jeśli teraz używasz basha, czy nadal jest wolny?
nneonneo
Świetne pytanie. Nie, jest szybki na bash.
Jason Swett
Czy nadal działa wolno, jeśli usuniesz ~/.z*pliki z drogi?
user4815162342
Nie. Więc myślę, że to coś w jednym z nich.
Jason Swett
4
Jeśli repozytorium jest duże, wywołanie git st za każdym razem może spowolnić działanie powłoki. Użyj tej opcji, aby ją wyłączyć. git config --add oh-my-zsh.hide-status 1
Senthil Kumar

Odpowiedzi:

188

Możesz dodać to do swojej konfiguracji git, a zsh nie będzie już sprawdzać statusu

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

Wyjaśnienie

W lib / git.zsh są dwie główne funkcje git :

  • git_prompt_info()
  • parse_git_dirty()

Każda metoda ma przełącznik konfiguracji git, aby ją wyłączyć:

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

Niektóre motywy tworzą własne zapytania git i czasami ignorują te flagi .

Pascalius
źródło
4
To rozwiązanie nadal działa, po prostu wypróbowałem to w moim folderze projektu Symfony2. Może folder dostawcy spowalnia pracę, tak jak folder rake w przypadku aplikacji railsowych? zsh jest teraz szybki, a i tak nie potrzebuję wtyczki zsh do GIT. Dzięki!
mblaettermann
To doskonale rozwiązało mój problem. Nadal mogę używać fajnego biznesu ze statusem git w innych repozytoriach, ale nie w moim ogromnym repozytorium kodu źródłowego Firefoksa, gdzie działa wolno.
Leo Ufimtsev
1
Musiałem użyć oh-my-zsh.hide-dirty. Mogło się zmienić, a może mój motyw (agnoster) tylko szanuje hide-dirty.
Benjamin Atkin
1
Robienie tego w ustawieniach globalnych dla vagrant virtualbox vms z --globaljest naprawdę przydatne (wolno w trybie gościa, szybko na hoście), jak opisano tutaj: stackoverflow.com/a/40943155/1092815 <3
GabLeRoux
7
git config --add oh-my-zsh.hide-dirty 1było wszystkim, czego potrzebowałem do mojego powolnego repo.
Johnathan Elmore
28

Oh_my_zsh wydaje się działać wolno w przypadku niektórych repozytoriów, ponieważ po każdym poleceniu sprawdza stan repozytorium. To zachowanie można zmienić w nowej wersji pliku .oh_my_zsh. Po prostu odkomentuj następujący wiersz w .zshrc:

DISABLE_UNTRACKED_FILES_DIRTY = „prawda”

Następnie uruchom ponownie terminal lub wykonaj następujące czynności:

źródło ~ / .zshrc

Peeyush Goela
źródło
4
git config --add oh-my-zsh.hide-status 1przyspiesza działanie, ale całkowicie usuwa status zsh VCS. Ten utrzymuje go i nadal przyspiesza.
nyxz
1
Miałem nadzieję, że to załatwi sprawę, ale bez efektu, nawet po źródle ~ / .zshrc. git config --add oh-my-zsh.hide-dirty 1jednak dla mnie zadziałało. git config --global --add oh-my-zsh.hide-dirty 1aby wyłączyć to dla wszystkich repozytoriów.
Johnathan Elmore
@JohnathanElmore @Peeyush, DISABLE_UNTRACKED_FILES_DIRTY="true"nie robi tego samego, co oh-my-zsh.hide-dirtyustawienie, mimo że są podobne. Zobacz kod tutaj: github.com/ohmyzsh/ohmyzsh/blob/master/lib/git.zsh#L17 . To DISABLE_UNTRACKED_FILES_DIRTYustawienie po prostu dodaje --untracked-files=noflagę do git statuspolecenia, podczas gdy oh-my-zsh.hide-dirty 1ustawienie git statuscałkowicie pominie całe polecenie. Polecam sugestię @ JohnathanElmore dotyczącą globalnych ustawień konfiguracji git.
stwr667
14

Może to być motyw wywołujący git i rvm po każdym poleceniu.

U mnie zmiana ZSH_THEME="juanghurtadoto"na ZSH_THEME="miloshadzic"całkowite usunięcie 2-sekundowego opóźnienia po każdym poleceniu.

Motywy można znaleźć na https://github.com/robbyrussell/oh-my-zsh/wiki/themes

James EJ
źródło
Ciekawy. +1. To jest bardziej szczegółowe niż moja odpowiedź.
VonC,
13

Dla mnie jest wolny na VirtualBox (gość), ponieważ używam zsynchronizowanego folderu. Nadal chcę, aby był włączony w systemie OS X (host), gdzie jest wystarczająco szybki. Zamiast korzystać z lokalnych ustawień konfiguracyjnych, które są przechowywane w repozytorium i zmieniłyby je zarówno na gościu, jak i na hoście, używam globalnych ustawień konfiguracyjnych tylko dla gościa :

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

Jeśli chcę tego tylko dla jednego repozytorium:

git config --add oh-my-zsh.hide-dirty 1
Benjamin Atkin
źródło
11

Istnieją różne sposoby na przyspieszenie procesu oh-my-zsh, jak opisano szczegółowo w sekcji „ zsh uruchamia się niezwykle wolno ”, czyszcząc sekcję dotyczącą wtyczek.

Na przykład w poście na blogu „ Naprawa powolnego działania zachęty oh-my-zsh git-svn ” wspomniano o tej parse_git_dirtyfunkcji jako potencjalnym problemie.

VonC
źródło
Te rzeczy pomogły w tym, że zacząłem komentować rzeczy, aby zobaczyć, co może przyspieszyć ładowanie. Jeszcze bardziej zawęziłem problem i zaktualizowałem pytanie.
Jason Swett
Post compinit poprawił trochę dla mnie, ale usunięcie parse_git_dirty naprawdę przyspieszyło pracę. Dzięki.
Raj
6

W końcu to rozgryzłem. Mój projekt miał rakefolder z mnóstwem plików (około 20 000). Nie mam pojęcia, do czego służył ten folder, ale usunąłem go, Zsh nie jest już wolny, a moja aplikacja nadal działa.

Jason Swett
źródło
Ciekawe informacje zwrotne (dokładniejsze niż moja odpowiedź) +1
VonC
5
I zajęło mi to tylko 4 miesiące!
Jason Swett
Uważam, że szybko! Znam niektórych, którym zajmuje to kilka lat ;) meta.stackexchange.com/questions/36318/…
VonC
3

Jeśli nie obchodzą Cię inne programy do kontroli wersji, ale gitmożesz po prostu wyłączyć wszystkie vcs_infopliki w swoim *.zsh-themei zastąpić je natywnymigit poleceniami.

Na przykład poprawiam moje agnoster.zsh-themeprzez:

  1. skomentuj / usuń wszystkie linie, które mają vcs_info,
  2. edytuj kod w prompt_git()funkcji z:

    ref="$vcs_info_msg_0_" do

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

Zasadniczo po prostu wyłączyłem wszystkie vcs_infoakcje i zamiast tego użyłem natywnego gitpolecenia do sprawdzania statusów repozytorium. W rezultacie nadal widzę mój przydatny znak zachęty git z szybkością równą pracy w katalogu innym niż git. Dzięki tej niewielkiej modyfikacji mój zsh może działać 4-5x szybciej w repozytoriach git.

Uwaga: użyj GNU grep, a nie BSD grep.

fronthem
źródło
1

Powyższe odpowiedzi nie rozwiązały mojego problemu. W moim przypadku funkcja git_prompt_statuszajmuje zbyt dużo czasu niż inne. Więc zmodyfikowałem ~ / .oh-my-zsh / lib / git.zsh, zastępując git_prompt_statusfunkcję moją wczesną wersją zwrotną:

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
}

Chociaż używam ZSH_THEME_GIT_PROMPT_MODIFIED jako oznaczenia nieokreślonego, możesz wybrać dowolny status, który chcesz, aby to wskazać lub zaimplementować znacznie szybszą git_prompt_statusfunkcję w swoim przypadku.

Xavier.S
źródło
0

Dla każdego, kto używa motywu statku kosmicznego, dodaj to do .zshrc:

SPACESHIP_GIT_STATUS_SHOW="false"

pracował dla mnie. Oczywiście utracisz status git w monicie terminala.

Opcje git dla tego motywu można znaleźć tutaj

Harpal
źródło