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. Есть ли другие флаги, которые я могу запустить, чтобы найти узкое место?
Ответы
Ответ 1
В Git для Windows 2.19 (сентябрь 2018 г.) git stash
(и git 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
.
А также:
Старый скрипт оболочки 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 вызывается напрямую, а не сценарием оболочки.
Есть оптимизации:
Этот коммит вводит оптимизацию, избегая повторного вызова тех же функций.
Например, 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