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

Способы улучшения производительности git status

У меня есть репо 10 ГБ на машине с Linux, которая находится на NFS. Первый git status занимает 36 минут, а последующий git status занимает 8 минут. Кажется, Git зависит от ОС для кэширования файлов. Только первые команды git такие как commit, status которое включает упаковку/переупаковку всего репо, занимает очень много времени для огромного репо. Я не уверен, что вы использовали git status в таком большом репо, но кто-нибудь сталкивался с этой проблемой?

Я пробовал git gc, git clean, git repack но затраченное время остается/почти таким же.

Помогут ли субмодули или какие-либо другие концепции, такие как разбиение репо на более мелкие? Если это так, что лучше для разделения большого репо. Есть ли другой способ улучшить время, затрачиваемое на команды git в большом репо?

4b9b3361

Ответ 1

Чтобы быть более точным, git зависит от эффективности системного вызова lstat(2), поэтому настройка ваших клиентов "тайм-аутом кэша атрибутов" может помочь.

Руководство по git-update-index - по сути, ручной режим для git-status - описывает, что вы можете сделать, чтобы облегчить это, используя флаг --assume-unchanged чтобы подавить его нормальное поведение и вручную обновить пути, которые вы изменили, Вы даже можете запрограммировать свой редактор на сброс этого флага каждый раз, когда вы сохраняете файл.

Альтернатива, как вы предлагаете, состоит в том, чтобы уменьшить размер вашей проверки (размер упаковочных файлов здесь не вступает в игру). Варианты разреженных фотографии, Подмодули или Googles репо инструмент.

(Есть ветка списка рассылки об использовании Git с NFS, но она не отвечает на многие вопросы.)

Ответ 2

Я также вижу эту проблему в большом проекте, разделяемом над NFS.

Мне потребовалось некоторое время, чтобы обнаружить флаг -uno, который может быть присвоен как статусу git commit, так и git.

Что делает этот флаг, так это отключить поиск ненужных файлов. Это значительно сокращает количество операций nfs. Причина в том, что для того, чтобы git обнаруживать невоспроизводимые файлы, он должен искать во всех подкаталогах, поэтому, если у вас много подкаталогов, это повредит вам. Отключив git от поиска ненужных файлов, вы устраните все эти операции NFS.

Объедините это с флагом core.preloadindex, и вы сможете получить резонансную производительность даже на NFS.

Ответ 3

Попробуйте git gc. Также может помочь git clean.

ОБНОВЛЕНИЕ - Не знаю, откуда пришло отрицательное голосование, но в руководстве по git конкретно сказано:

Запускает ряд служебных задач в текущем репозитории, таких как сжатие файловых ревизий (чтобы уменьшить дисковое пространство и повысить производительность) и удаление недоступных объектов, которые могли быть созданы из предыдущих вызовов git add.

Пользователям рекомендуется выполнять эту задачу на регулярной основе в каждом хранилище, чтобы поддерживать хорошее использование дискового пространства и хорошую производительность.

Я всегда замечаю разницу после запуска git gc, когда состояние git медленное!

ОБНОВЛЕНИЕ II - Не уверен, как я пропустил это, но ОП уже пробовал git gc и git clean. Клянусь, этого изначально не было, но я не вижу никаких изменений в правках. Простите за это!

Ответ 4

Если ваш репозиторий git сильно использует подмодули, вы можете значительно повысить производительность git, отредактировав конфигурационный файл в каталоге .git и установив ignore = dirty на любых особо больших/тяжелых подмодулях. Например:

[submodule "mysubmodule"]
url = ssh://mysubmoduleURL
ignore = dirty

Вы потеряете удобство напоминания о том, что есть неустановленные изменения в любом из подмодулей, о которых вы, возможно, забыли, но вы по-прежнему сохраняете основное удобство знать, когда подмодули не синхронизированы с основным Сделки рЕПО. Кроме того, вы все равно можете сменить рабочий каталог на сам подмодуль и использовать в нем статус git, как обычно, для получения дополнительной информации. См. этот вопрос для получения более подробной информации о том, что означает "грязный".

Ответ 5

Производительность статуса git должна улучшиться с Git 2.13 (второй квартал 2017 года).

См. коммит 950a234 (14 апреля 2017 г.) Джеффа Хостетлера (jeffhostetler) . (Merged by Junio C Hamano -- [TG41] -- in commit 8b6bba6, 24 Apr 2017)
(Merged by Junio C Hamano -- [TG41] -- in commit 8b6bba6, 24 Apr 2017)

string-list: используйте макрос ALLOC_GROW при восстановлении string_list

Используйте макрос ALLOC_GROW() при повторном расположении массива string_list вместо того, чтобы просто увеличить его на 32.
Это оптимизация производительности.

Во время статуса на очень большой репо и есть много изменений, значительный процент от общего времени выполнения тратится на пересечение массива wt_status.changes.

Это изменение уменьшает время в wt_status_collect_changes_worktree() со 125 до 45 секунд в моем очень большом хранилище.


Кроме того, в Git 2.17 (Q2 2018) будет представлена новая трассировка для измерения времени, потраченного на операции с индексами.

См. коммит ca54d9b (27 января 2018 г.) от Нгуен Тай Нгок Дуй (pclouds).
(Merged by Junio C Hamano -- [TG410] -- in commit 090dbea, 15 Feb 2018)

trace: измерьте время, затрачиваемое на операции с большим индексом

Все известные блоки тяжелого кода измеряются (кроме объектной базы данных доступ). Это должно помочь определить, эффективна ли оптимизация или нет.
Неоптимизированный git-статус даст что-то вроде ниже:

0.001791141 s: read cache ...
0.004011363 s: preload index
0.000516161 s: refresh index
0.003139257 s: git command: ... 'status' '--porcelain=2'
0.006788129 s: diff-files
0.002090267 s: diff-index
0.001885735 s: initialize name hash
0.032013138 s: read directory
0.051781209 s: git command: './git' 'status'

Тот же Git 2.17 (Q2 2018) улучшает git status с помощью:

revision.c: уменьшить количество запросов к объектной базе данных

В mark_parents_uninteresting() мы проверяем существование объектный файл, чтобы увидеть, должны ли мы рассматривать коммит как проанализированный. Результат установить бит "parsed" в коммите.

Измените условие, чтобы проверить только has_object_file(), если результат изменит разобранный бит.

Когда локальная ветвь отличается от своей вышестоящей ссылки, "git status" будет вычислять счет вперед/назад.
Это использует paint_down_to_common() и нажимает mark_parents_uninteresting().

На копии репозитория Linux с локальным экземпляром "master" за удаленной веткой "origin/master" ~ 60 000 коммитов мы видим производительность "git status" увеличился с 1,42 до 1,32 секунды разница -7.0%.


В Git 2.24 (Q3 2019) предлагается еще один параметр для улучшения производительности git status:

См. commit aaf633c, commit c6cc4c5, commit ad0fb65, commit 31b1de6, commit b068d9a, commit 7211b9e (13 августа 2019 г.) от Деррика Столи (derrickstolee).
(Merged by Junio C Hamano -- [TG429] -- in commit f4f8dfe, 09 Sep 2019)

Настройки репо: создать настройку feature.manyFiles

Настройка feature.manyFiles подходит для репо со многими файлы в рабочем каталоге.
Установив index.version=4 и core.untrackedCache=true, такие команды, как "git status", должны улучшиться.

Ответ 6

git config --global core.preloadIndex true

Работала для меня. Проверьте официальную документацию здесь.

Ответ 7

В нашей кодовой базе, где мы имеем где-то в диапазоне 20-30 подмодулей,
git status --ignore-submodules
ускорил дело ради меня. Обратите внимание, что это не будет сообщать о статусе субмодулей.

Ответ 8

Что-то, что еще не было упомянуто, - это активировать кэш файловой системы на компьютерах с Windows (файловые системы linux совершенно разные, и git был оптимизирован для них, поэтому, вероятно, это помогает только для Windows).

git config core.fscache true


В крайнем случае, если git все еще работает медленно, можно отключить проверку времени модификации, так что git должен выяснить, какие файлы изменились.
git config core.ignoreStat true

НО: измененные файлы должны быть добавлены самим разработчиком с помощью git add. Git не находит изменений сам.

источник

Ответ 9

Я не знаю, какой в этом смысл, но для меня статус занимал 30 минут, я перепробовал все, что смог найти в Интернете, наконец, я сделал git reset меня было 100 изменений, которые я применил из stash, из которого был создан stash. другая ветка, но примененная к этой ветке, они были все поставлены, но не зафиксированы (просто объясняя, что я делал по-другому, прежде чем столкнуться с этой проблемой), git reset занял 15 минут, но после этого все начало работать быстро, менее чем за секунду для статуса, Я не эксперт по git, просто рассказываю, что решило мою проблему, надеюсь, это поможет другим, кто попадет на эту страницу.

Ответ 10

Оставшиеся index.lock файлы

git status может быть патологически медленным, если у вас есть оставшиеся файлы index.lock.

Это особенно актуально, когда у вас есть git submodules, потому что тогда вы часто не замечаете такие файлы для последующего перехода.

Резюме: Запустите find .git/ -name index.lock и удалите оставшиеся файлы, проверив, что они действительно не используются ни одной из запущенных в настоящее время программ.


Подробнее

Я обнаружил, что состояние моего git-оболочки было очень медленным в репозитории, с git 2.19 в Ubuntu 16.04.

Вскочил и обнаружил, что /usr/bin/time git status в моем подмодуле assets git занял 1,7 секунды.

Нашел с strace, что git читает все мои большие файлы там с mmap. Обычно этого не делается, обычно достаточно stat.

Я погуглил проблему и обнаружил использование индекса и проблему Racy Git.

Попытка git update-index somefile (в моем случае gitignore в проверке субмодуля) показала здесь но это не удалось с

fatal: Unable to create '/home/niklas/src/myproject/.git/modules/assets/index.lock': File exists.

Another git process seems to be running in this repository, e.g.
an editor opened by 'git commit'. Please make sure all processes
are terminated then try again. If it still fails, a git process
may have crashed in this repository earlier:
remove the file manually to continue.

Это классическая ошибка. Обычно вы замечаете это на любой операции git, но для подмодулей, которые вы не часто делаете, вы можете не замечать это месяцами, потому что это появляется только при добавлении чего-либо в индекс; предупреждение не выводится только для чтения git status.

После удаления файла index.lock git status сразу стал быстрым, mmaps исчез, и теперь он более чем в 1000 раз быстрее.

Так что, если ваш статус мерзавца неестественно медленный, проверьте find .git/ -name index.lock и удалите остатки.