Подтвердить что ты не робот

Git Задержка медленнее на окнах

На моей машине Windows git stash на каждый вызов приходится около 3,5 секунд, что добавляет около 7 секунд к моему крюку фиксации git.

Та же команда под Linux (тот же самый компьютер) занимает около 0,01 секунды. Проблема производительности также относится к пустым репозиториям.

Я пробовал следующее из этого потока и этот поток:

  • core.fscache - true
  • core.preloadindex установлен на true
  • gc.auto установлено значение 256
  • Настройка PS1 = '$'
  • Запуск cmd в режиме администрирования
  • Запуск внутри cmd.exe вместо git - bash

Запуск GIT_TRACE=true git stash list

16:58:16.844591 git.c:563               trace: exec: 'git-stash' 'list'
16:58:16.844591 run-command.c:336       trace: run_command: 'git-stash' 'list'
16:58:19.699591 git.c:350               trace: built-in: git 'rev-parse' '--git-dir'
16:58:19.859591 git.c:350               trace: built-in: git 'rev-parse' '--git-path' 'objects'
16:58:20.069591 git.c:350               trace: built-in: git 'rev-parse' '--show-toplevel'
16:58:20.154591 git.c:350               trace: built-in: git 'rev-parse' '--git-path' 'index'
16:58:20.244591 git.c:350               trace: built-in: git 'config' '--get-colorbool' 'color.interactive'
16:58:20.334591 git.c:350               trace: built-in: git 'config' '--get-color' 'color.interactive.help' 'red bold'
16:58:20.424591 git.c:350               trace: built-in: git 'config' '--get-color' '' 'reset'
16:58:20.514591 git.c:350               trace: built-in: git 'rev-parse' '--verify' '--quiet' 'refs/stash'

real    0m3.845s
user    0m0.000s
sys     0m0.047s

Запуск GIT_TRACE_PERFORMANCE=true git stash list

16:59:18.414591 trace.c:420             performance: 0.001078046 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'rev-parse' '--git-dir'                                          
16:59:18.569591 trace.c:420             performance: 0.000947184 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'rev-parse' '--git-path' 'objects'                               
16:59:18.779591 trace.c:420             performance: 0.001253627 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'rev-parse' '--show-toplevel'                                    
16:59:18.869591 trace.c:420             performance: 0.001285517 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'rev-parse' '--git-path' 'index'                                 
16:59:18.955591 trace.c:420             performance: 0.001139994 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'config' '--get-colorbool' 'color.interactive'                   
16:59:19.040591 trace.c:420             performance: 0.001182881 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'config' '--get-color' 'color.interactive.help' 'red bold'       
16:59:19.125591 trace.c:420             performance: 0.001128997 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'config' '--get-color' '' 'reset'                                
16:59:19.215591 trace.c:420             performance: 0.001567766 s: git command: 'C:\Program Files\Git\mingw64\libexec\git-core\git.exe' 'rev-parse' '--verify' '--quiet' 'refs/stash'                    
16:59:19.295591 trace.c:420             performance: 3.730583540 s: git command: 'C:\Program Files\Git\mingw64\bin\git.exe' 'stash' 'list'                                                                

real    0m3.819s                                                                                                                                                                                          
user    0m0.000s                                                                                                                                                                                          
sys     0m0.062s                                                                                                                                                                                          

Из журнала мы видим, что между командой git -stash выполняется и занимает около 3 секунд, и выполняется git -rev-parse. Есть ли другие флаги, которые я могу запустить, чтобы найти узкое место?

4b9b3361

Ответ 1

В Git для Windows 2.19 (сентябрь 2018 г.) git stashgit rebase) больше не предназначены только для сценариев, а представляют собой двоичный файл, скомпилированный с помощью git.exe.
Смотрите git-for-windows/build-extra PR 203.

Чтобы активировать их, введите:

git config --global rebase.useBuiltin true
git config --global stash.useBuiltin true

Предупреждение:

Как бы ни были хороши скорости -u ps, рассматриваемые патчи все еще находятся в движении, и они вообще не проверены в бою.

Итак, на данный момент версия скрипта git stash остается по умолчанию, вот так:

  • пользователи, которые хотят получить непосредственное улучшение скорости в трех проектах Google Summer of Code, работающих параллельно,
  • в то время как другие, которые не хотят играть в морскую свинку, выполняя только хорошо проверенный код, могут остаться в безопасности.

Суть остается: в следующих версиях Git сценарий bash для git-stash со временем исчезнет, и его замена будет и будет быстрее.


Обновление Q2 2019, с Git 2.22, git stash полностью переписан на C.

См совершать 40af146, совершать 48ee24a, совершают ef0f0b4, совершают 64fe9c2, совершают 1ac528c, совершают d553f53, совершают d4788af, совершают 41e0dd5, совершают dc7bd38, совершают 130f269, совершают bef55dc, совершают dac566c, совершают ab8ad46 (25 февраля 2019) от Paul-Себастьян Унгуряну (weekly-digest[bot]).
См. Коммит c4de61d, коммит 577c199, коммит 4e2dd39, коммит 8a0fc8d (25 февраля 2019 г.). Автор Joel Teichroeb (klusark).
См. Коммит 7906af0, коммит 90a4627, коммит 8d8e9c2 (25 февраля 2019 г.) Иоганнеса dscho (dscho).
(Объединено Junio C Hamano - gitster - в коммите e36adf7, 22 апреля 2019 г.)

Вы все еще можете использовать скрипт оболочки с git legacy-stash.

А также:

stash: конвертировать stash--helper.c в stash.c

Старый скрипт оболочки git-stash.sh был удален и полностью заменен builtin/stash.c.
Для этого команды create и push были адаптированы для работы без stash.sh.

Например, перед этим коммитом git stash create называется git stash--helper create --message "$*". Если бы он вызвал git stash--helper create "[email protected]", то некоторые из этих изменений не были бы необходимы.

Этот коммит также удаляет слово helper так как теперь stash вызывается напрямую, а не сценарием оболочки.

Есть оптимизации:

stash: оптимизировать get_untracked_files() и check_changes()

Этот коммит вводит оптимизацию, избегая повторного вызова тех же функций.
Например, git stash push -u вызовет в некоторых моментах следующие функции:

  • check_changes() (внутри do_push_stash())
  • do_create_stash(), которая вызывает: check_changes() и get_untracked_files()

Обратите внимание, что check_changes() также вызывает get_untracked_files().
Итак, check_changes() вызывается 2 раза, а get_untracked_files() 3 раза.

Старая функция check_changes() теперь состоит из двух функций: get_untracked_files() и check_changes_tracked_files().

Это цепочки вызовов для push и create:

  • push_stash()do_push_stash()do_create_stash()
  • create_stash()do_create_stash()

Чтобы не вызывать одни и те же функции снова и снова, check_changes() внутри do_create_stash() теперь помещается в функции вызывающей стороны (create_stash() и do_push_stash()).
Таким образом, check_changes() и get_untracked files() вызываются только один раз.

Ответ 2

git-stash - это script, а не команда, скомпилированная в двоичном формате git.exe.

В linux: я могу найти git-stash в /usr/lib/git-core/git-stash - я позволю вам искать правильный путь к окнам...


Этот script использует #!/bin/sh для запуска, я не знаю, какая реализация оболочки используется, когда вы запускаете это в окнах.

Вы можете попробовать запустить его с другой совместимой оболочкой (здесь: bash):

# the git-core/ dir needs to be in the PATH,
# obviously  you will need to provide the correct path for your git-core dir

$ PATH=/usr/lib/git-core:$PATH bash /usr/lib/git-core/git-stash

Вы также можете повернуть флаг -x, который будет печатать трассировку всех выполняемых команд, и визуально проверить, является ли одна из подкоманд, как вешалка:

$ PATH=/usr/lib/git-core:$PATH bash -x /usr/lib/git-core/git-stash