Способы улучшения производительности git status - PullRequest
66 голосов
/ 14 февраля 2011

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

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

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

Ответы [ 9 ]

40 голосов
/ 14 февраля 2011

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

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

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

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

32 голосов
/ 31 мая 2012

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

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

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

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

26 голосов
/ 24 мая 2016

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

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

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

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

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

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

15 голосов
/ 24 августа 2012

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

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

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

7 голосов
/ 26 апреля 2017

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

См. коммит 950a234 (14 апреля 2017) Джефф Хостетлер (jeffhostetler) .
(Объединено Junio ​​C Hamano - gitster - в коммит 8b6bba6 , 24 апреля 2017 г.)

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

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

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

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


Plus, Git2.17 (Q2 2018) введет новую трассировку для измерения времени, потраченного на операции с индексами.

См. commit ca54d9b (27 января 2018 года) Nguy Thn Thái Ngọc Duy (pclouds) .
(объединено Junio ​​C Hamano - gitster - в commit 090dbea , 15 февраля 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%.

1 голос
/ 16 апреля 2019

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

1 голос
/ 23 января 2018

git config --global core.preloadIndex true

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

0 голосов
/ 03 июля 2019

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

git config core.fscache true


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

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

источник

0 голосов
/ 02 февраля 2018

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

...