Я пытаюсь клонировать репозиторий с большим количеством BLOB-объектов в его истории и хотел бы загружать файлы только при определенном коммите без каких-либо дополнительных затрат или избыточности.
При попытке git clone --depth 1
каталог .git
становится довольно большим. Похоже, это связано с большим пакетным файлом, размер которого соответствует размеру, сообщаемому git, когда он равен Receiving objects:
. Проверка пак-файла с помощью git verify-pack
предполагает, что он содержит большое количество информации о больших двоичных объектах.
Однако попытка git clone --filter=blob:none
по-прежнему приводит к получению таких же больших BLOB-объектов со списком пакетных файлов.
Я ожидаю, что --depth 1
не должен загружать какую-либо историю, а filter=blob:none
не должен загружать историю больших двоичных объектов.
Так почему же мой каталог .git
заполняется служебными файлами Packfile для поверхностного клона?
Мне интересно, возможно, это первоначальная сжатая загрузка единственного коммита, который я проверил, - но даже в этом случае, как я могу предотвратить сохранение этого избыточного файла?
Для справки: репозиторий, который я клонирую: ARM-software/CMSIS_5.
Это началось с вопроса о мелких подмодулях и загрузке файлов только при определенном коммите без накладных расходов, но накладные расходы на паковочные файлы, похоже, относятся к клонированию в целом, поэтому я решил начать здесь.
В этом случае я по-прежнему хочу, чтобы каталог сохранял свою идентичность репозитория (в конечном итоге, потому что я хочу использовать его в качестве подмодуля без явной необходимости в истории подмодуля). Если нужные мне файлы создаются из больших двоичных объектов, есть ли способ «обрезать» большие двоичные объекты (т. е. пакетный файл) после создания извлеченных файлов?
Если я запущу git clone --filter blob:none https://github.com/ARM-software/CMSIS_5/
, размер полученного репозитория составит всего 78M
. Это крошечно. Кажется, что все идет так, как ожидалось. Без фильтра репозиторий примерно 313M
. (кстати, я использую git версии 2.45.2)
@chepner, похоже, ты не знаком с частичными клонами.
@larsks Да, --filter=blob:none
конечно отфильтровывает BLOB-объекты (и --depth 1
успешно клонирует неглубоко; git 2.43.0). Мой вопрос, скорее, связан с попыткой понять, почему один пакетный файл в .git/objects/pack/
занимает ~30% этого места для хранения (особенно для --depth 1
, где я не ожидаю никакой истории) и почему этот пакетный файл содержит большие двоичные объекты (особенно для --filter=blob:none
, где я не ожидайте никаких исторических пятен).
Вам нужны большие двоичные объекты, соответствующие файлам в вашем рабочем дереве. Когда я клонирую репозиторий, имеется примерно 3225 файлов и 2807 больших двоичных объектов (возможно, из-за дублирования или чего-то еще, я не проверял более подробно, но все кажется разумным и ожидаемым).
@larsks Думаю, я понимаю. Если вы предложите ответ, описывающий необходимость этих блоков, когда они избыточны для текущего рабочего дерева, я с радостью отмечу его как решение.
Я опубликовал (свободное) продолжение этого вопроса с точки зрения подмодулей здесь, для всех, кто следит за хлебными крошками.
Проверка файла пакета с помощью gitverify-pack показывает, что он содержит большое количество информации о больших двоичных объектах.
Когда ты бежишь...
git clone --filter blob:none --depth 1 https://github.com/ARM-software/CMSIS_5
... вы все еще извлекаете рабочую копию из репозитория. В рассматриваемом репозитории содержится более 3000 файлов:
$ find * -type f -print | wc -l
3225
Поскольку содержимое файла хранится в больших двоичных объектах, это означает, что независимо от фильтра blob:none
, git
все равно потребуется передавать большие двоичные объекты, соответствующие файлам в коммите HEAD, поэтому мы ожидаем увидеть аналогичную величину больших двоичных объектов в паковочных файлах. И действительно, после выполнения приведенной выше команды мы видим:
$ git verify-pack -v .git/objects/pack/pack-b0279f34420775288c089456dfc84f2697570837.pack |
grep blob | wc -l
2807
Если вы не извлекаете рабочую копию (например, клонируете с помощью --bare
), результирующий репозиторий не будет содержать никаких больших двоичных объектов:
$ git clone --bare --filter blob:none --depth=1 https://github.com/ARM-software/CMSIS_5/
$ find CMSIS_5.git/objects/pack/ -name '*.pack' | xargs -n1 git verify-pack -v | grep blob | wc -l
0
Спасибо, @larsks. Я думаю, что недостающей частью для меня было понимание того, что для заполнения рабочего каталога его сначала необходимо получить в пакетном файле. Я искал способ (автоматически) удалить избыточный пакетный файл после заполнения рабочего дерева, но я считаю, что это имеет смысл только в конкретном случае поверхностного статического клона, и поэтому я могу понять, почему это не особенность git.
git clone
создает репозиторий, состоящий из больших двоичных объектов. Нужные вам файлы создаются из больших двоичных объектов. Если вам нужны только файлы, вам нужен не репозиторий, а, возможно, архив (созданный с помощьюgit archive
из репозитория).