Воздействие большого количества ветвей в репозиторий git?

Кто-нибудь знает, какое влияние оказывает репо с git, которое имеет много веток (2000+)? Увеличивает ли git pull или git fetch из-за того, что у него много ветвей? Если есть разница, укажите контрольные показатели.

Ответ 1

Как отмечали другие, ветки и другие ссылки - это просто файлы в файловой системе (за исключением того, что это не совсем верно из-за упакованных ссылок) и довольно дешевы, но это не значит, что их число не может повлиять на производительность. См. Плохая толчка с большим количеством ссылок refs в списке рассылки Git для недавнего (декабрь 2014) примера Git производительности пострадали от наличия 20k refs в репозитории.

Если я правильно напомню, что некоторая часть обработки ref была O (n²) несколько лет назад, но с тех пор это было очень хорошо. Там repo-обсудить поток с марта 2012 года, который содержит некоторые потенциально полезные детали, если возможно, датированные и специфичные для JGit.

В нескольких версиях Scaling Gerrit обсуждаются (помимо прочего) потенциальные проблемы с высоким количеством ссылок, но также отмечается, что несколько сайтов имеют gits с более чем 100k refs. У нас есть Git с ~ 150k refs, и я не думаю, что мы видим проблемы с производительностью.

Один аспект наличия большого количества ссылок - это размер рекламы ref в начале некоторых транзакций Git. Размер рекламы вышеупомянутого 150k ref Git составляет около 10 МБ, то есть каждая операция git fetch будет загружать этот объем данных.

Итак, да, не игнорируйте проблему полностью, но вы не должны терять сон за 2000 refs.

Ответ 2

Март 2015 года: у меня нет эталонных тестов, но один способ гарантировать, что git fetch остается разумным, даже если в репозитории обратного потока имеется большой набор ветвей, будет специфический менее общий refspec чем тот по умолчанию.

fetch = +refs/heads/*:refs/remotes/origin/*

Вы можете добавить столько удаленных refspecs к удаленному устройству, сколько захотите, эффективно заменив всеобъемлющую refspec выше на более конкретные спецификации, чтобы просто включить ветки, которые вам действительно нужны (даже если в удаленном репо их тысячи)

fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/br*:refs/remotes/origin/br*
fetch = +refs/heads/mybranch:refs/remotes/origin/mybranch
....

Апрель 2018 года: git fetch улучшится с Git 2.18 (Q2 2018).

Смотрите коммит 024aa46 (14 марта 2018 г.) от Такуто Икуты (atetubou).
(Merged by Junio C Hamano -- [TG45] -- in commit 5d806b7, 09 Apr 2018)

fetch-pack.c: используйте oidset, чтобы проверить наличие свободного объекта

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

Вместо того, чтобы делать столько вызовов lstat(2), сколько ссылок удаленной стороны рекламируется, чтобы увидеть, существуют ли эти объекты в свободной форме, сначала заранее перечислить все существующие свободные объекты в hashmap и использовать чтобы проверить их наличие, если количество ссылок больше, чем количество незакрепленных предметов.

С помощью этого патча количество вызовов lstat(2) в git fetch уменьшается от 411412 до 13794 для хранилища хрома, он имеет более 480000 удаленные ссылки.

Я взял временную статистику git fetch, когда происходит сборка для хрома хранилище 3 раза на Linux с SSD.

* with this patch
8.105s
8.309s
7.640s
avg: 8.018s

* master
12.287s
11.175s
12.227s
avg: 11.896s

На моем MacBook Air с более медленным lstat (2).

* with this patch
14.501s

* master
1m16.027s

git fetch на медленном диске будет значительно улучшено.


Обратите внимание, что hashmap, используемый в packfile, улучшается в Git 2.24 (Q4 2019)

См. commit e2b5038, commit 404ab78, commit 23dee69, commit c8e424c, commit 8a973d0, commit 87571c3, коммит 939af16, коммит f23a465, коммит f0e63c4, коммит 6bcbdfb, коммит 973d5ee, коммит 26b455f, коммит 28ee794, коммит b6c5241, коммит b94e5c1, коммит f6eb6bd, коммит d22245a, зафиксировать d0a48a0, зафиксировать 12878c8, зафиксировать e010a41 (06 октября 2019 г.) от Эрика Вонга (ele828).
Предложил: Филипп Вуд (phillipwood).
(Merged by Junio C Hamano -- [TG416] -- in commit 5efabc7, 15 Oct 2019)

Например:

packfile: использовать hashmap_entry в delta_base_cache_entry

Signed-off-by: Eric Wong
Reviewed-by: Derrick Stolee

Эта функция hashmap_entry_init предназначена для получения указателя структуры hashmap_entry, а не указателя структуры hashmap.

Это не было замечено, потому что hashmap_entry_init принимает аргумент "void *" вместо "struct hashmap_entry *", а структура hashmap больше и может быть преобразована в структуру hashmap_entry без повреждения данных.

Это имеет благоприятный побочный эффект - уменьшение размера delta_base_cache_entry со 104 байтов до 72 байтов в 64-битных системах.

Ответ 3

Да, да. Локально это не проблема, хотя это все равно влияет на несколько локальных команд. В частности, когда вы пытаетесь описать фиксацию на основе доступных ссылок.

В сети Git выполняется первичное объявление ref при подключении к нему для обновлений. Об этом можно узнать в документе pack protocol. Проблема здесь в том, что ваше сетевое соединение может быть шероховатым или скрытым, и в результате первоначальное объявление может занять некоторое время. Обсуждались устранение этого требования, но, как всегда, проблемы совместимости осложняют ситуацию. Последнее обсуждение этого вопроса здесь.

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

Ответ 4

Чтобы ответить на ваш вопрос, вы должны знать, как Git обрабатывать ветки. Что такое ветки?

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

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