Существует несколько жестких ограничений на количество файлов (технически объекты BLOB-объектов ), которые может хранить база данных Git. 1 Однако существует несколько более мягких ограничений.
У меня есть два удобных репозитория - FreeBSD и Linux, которые весят 5,7 и 6,7 миллиона объектов.Это намного меньше, чем 100 миллионов файлов: репозиторий Linux примерно на 1/15 от этого размера, и даже тогда файлов не так много, так как многие объекты являются коммитами и деревьями.
Обратите внимание, что существует разница между помещением 100 миллионов файлов в один коммит и размещением 100 миллионов файлов в 100 миллионов коммитов, каждый из которых хранит один файл.Первый потребует создания индекса, в котором содержится 100 миллионов файлов, что составляет несколько гигабайт файла индекса и, вероятно, будет медленным, но затем в нем будет храниться 100 миллионов BLOB-объектов, плюс один объект дерева на каталог и один коммит.Последний будет создавать небольшой индекс (из 1 файла), делать один коммит, используя одно дерево, содержащее один большой двоичный объект, а затем повторять 100 миллионов раз: индекс никогда не будет большим, но в хранилище будет храниться 300 миллионов объектов: 100 миллионов коммитов, каждый с1 дерево и 1 капля.
Не сразу видно, куда все время идет.git add <path>
требует:
- сжатие содержимого файла и создание нового объекта BLOB-объекта или повторное использование существующего объекта BLOB-объекта, если сжатый идентификатор хеша является идентификатором существующего объекта;затем
- обновляет индекс так, чтобы нулевой промежуточный слот соответствующего имени файла появлялся в правильной позиции.
Индекс сортируется, так что это обновление может быть очень быстрым, еслиновый файл идет в конце индекса, будет достаточно одного, однако, многобайтового добавления - или невероятно медленного: вставка впереди будет O (n 2 ) для числа записей, уже находящихся виндекс, так как все они должны будут двигаться вниз.На практике Git считывает индекс в память, выполняет там операцию и записывает индекс обратно, поэтому, вероятно, он будет очень медленным, когда индекс превысит некоторый порог размера (который будет варьироваться в зависимости от ОС и типа / скорости носителя данных)).
Вам также может понадобиться много дискового пространства между упаковываемыми объектами.Modern Git будет запускать git gc --auto
после каждого коммита, но между ранним Git и 2.17.0 (когда он был исправлен), git commit
случайно не сделал.Учитывая вашу ситуацию, вы, возможно, захотите отключить автоматический git gc
в любом случае и запускать его через контролируемые интервалы - или, как в документации, которую вы связали, используйте git fast-import
для создания файла пакета, не проходя по обычным каналам Git.Это позволит полностью избежать необходимости в индексе (пока вы не выполните от git checkout
до извлечения одного из этих коммитов, т.е.).
1 единственное реальное жесткое ограничение - это только 2 160 возможных хеш-идентификаторов.Тем не менее, вы сталкиваетесь с заметно высокой вероятностью коллизий хеш-функции, порядка 1 в 10 -18 - это также является указанием коэффициента ошибок по битам, указанного изготовителями дисков, к тому времени, когда вы достигаете примерно1,7 квадриллиона объектов.