Git LFS против стандартного Git: производительность для больших файлов
Сравнение Git LFS со стандартным Git для больших файлов, включая поведение при клонировании, файлы-указатели, отслеживание LFS и случаи, когда LFS стоит использовать.
Git LFS против стандартного Git: производительность для больших файлов
Git LFS против стандартного Git становится реальным вопросом, когда ваш репозиторий начинает содержать большие бинарные файлы. Исходный код обычно хорошо сжимается и диффается, но видео, дизайн-файлы, игровые текстуры, файлы моделей и большие наборы данных могут замедлить клонирование и усложнить очистку истории.
Git Large File Storage, обычно называемый Git LFS, облегчает обычный репозиторий Git, заменяя выбранные файлы небольшими файлами-указателями и храня реальное содержимое в хранилище объектов LFS. Этот компромисс помогает многим командам, но это не магия. Вам все равно нужно выбирать правильные файлы, фиксировать правила отслеживания и понимать, когда LFS загружает содержимое.
Узкое место производительности стандартного Git
Стандартный Git хранит зафиксированное содержимое в своей базе данных объектов и сохраняет достаточно истории для восстановления каждой зафиксированной версии. Это отлично работает для текстовых файлов. Это плохо работает, когда один и тот же файл размером 200 МБ изменяется много раз.
Две проблемы проявляются быстро:
- Бинарные форматы, такие как JPEG, MP4, ZIP, PSD и скомпилированные артефакты, часто плохо сжимаются с помощью дельта-сжатия.
- Удаленные файлы остаются в истории, если не переписать историю.
- Новые клоны платят за старые ошибки, потому что история Git все еще содержит эти старые объекты.
- Команды обслуживания репозитория имеют больше данных для проверки и упаковки.
Например, если команда фиксирует большой экспортированный дизайн-файл каждый спринт, удаление файла из текущей ветки позже не удаляет его старые версии из истории. Новые разработчики и CI-воркеры могут по-прежнему загружать данные, которые никто активно не использует.
Знакомство с Git Large File Storage (LFS)
Git LFS — это расширение, которое управляет выбранными файлами вне обычной базы данных объектов Git. Ваш репозиторий хранит небольшой текстовый указатель. Фактическое содержимое файла хранится в хранилище LFS, предоставляемом вашим Git-хостингом или другим LFS-сервером.
Система указателей
Указатель LFS выглядит так:
version https://git-lfs.github.com/spec/v1
oid sha256:4c2d44962ff3c43734e56598c199589d8995a643...a89c89
size 104857600
Этот указатель — то, что видит обычный Git. Клиент Git LFS загружает реальное содержимое файла, когда это необходимо для checkout или явной команды LFS.
Сравнение производительности: LFS против стандартного Git
| Операция | Стандартный Git | Git LFS |
|---|---|---|
| Первоначальное клонирование | Загружает историю Git, включающую зафиксированные большие объекты | Загружает историю Git с файлами-указателями; содержимое LFS может загружаться во время checkout в зависимости от конфигурации |
| Рост репозитория | Большие бинарники могут раздувать историю .git |
История Git остается меньше, так как содержимое отслеживаемых файлов находится вне репозитория |
| Checkout | Использует объекты, уже находящиеся в базе данных Git | Может потребоваться загрузка объектов LFS для фиксации, на которую выполняется checkout |
| CI-задачи | Могут тратить время на загрузку исторических файлов | Могут пропускать или ограничивать загрузку LFS, когда сборкам не нужны файлы |
| Очистка | Требует переписывания истории для удаления старых зафиксированных блобов | Все еще требует осторожности, но новые версии, отслеживаемые LFS, не раздувают обычную историю Git |
Важная деталь — поведение checkout. Обычный git clone с установленным Git LFS часто загружает файлы LFS, необходимые для фиксации, на которую выполняется checkout. Если вам нужны только указатели, используйте GIT_LFS_SKIP_SMUDGE=1 во время клонирования и загрузите файлы позже с помощью git lfs pull.
Когда использовать Git LFS
Git LFS хорошо подходит для файлов, которые являются большими, бинарными и ожидаемо изменяемыми. Распространенные примеры включают:
*.psd,*.tiff,*.blendи другие дизайн- или 3D-файлы.*.mp4,*.mov,*.wavи другие медиафайлы.- Большие файлы моделей, тестовые фикстуры или наборы данных, необходимые для проекта.
- Скомпилированные бинарники, только если у проекта есть четкая причина их версионировать.
Не помещайте каждый файл в LFS только потому, что можете. Текстовые файлы, исходный код, небольшие конфигурационные файлы и файлы, которые вы хотите, чтобы Git диффал нормально, должны оставаться в стандартном Git.
Проверьте лимиты хранилища и пропускной способности вашего хостинг-провайдера перед внедрением LFS. GitHub, GitLab, Bitbucket и самостоятельные платформы могут различаться в квотах, биллинге и политике хранения.
Внедрение Git LFS
Установите клиент Git LFS, затем включите его хуки для вашего пользователя:
git lfs install
Отслеживайте шаблоны, которые вы хотите, чтобы LFS управлял:
git lfs track "*.psd"
git lfs track "assets/*.mp4"
Эти команды создают или обновляют .gitattributes. Зафиксируйте этот файл вместе с файлами, которые он затрагивает:
git add .gitattributes assets/
git commit -m "Отслеживать дизайн-файлы с помощью Git LFS"
git push
Если большой файл уже был зафиксирован в обычной истории Git, отслеживание его с помощью LFS влияет только на будущие фиксации. Для миграции существующей истории используйте инструмент миграции, такой как git lfs migrate import, и координируйте действия осторожно, так как переписывание истории изменяет идентификаторы фиксаций.
Чтобы клонировать без немедленной загрузки содержимого LFS, используйте:
GIT_LFS_SKIP_SMUDGE=1 git clone [email protected]:example/assets-heavy-repo.git
cd assets-heavy-repo
git lfs pull --include="assets/*.mp4"
Практический вывод
Используйте стандартный Git для исходного кода и небольших текстовых файлов. Используйте Git LFS для больших бинарных файлов, которые должны быть в репозитории, но не должны раздувать обычную историю Git.
Для командного репозитория добавляйте правила LFS заранее, фиксируйте .gitattributes, документируйте, как CI обрабатывает загрузки LFS, и проверяйте лимиты LFS вашего хостинга. Это даст вам преимущество в производительности без неожиданностей для разработчиков во время клонирования, checkout или сборок релизов.