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 или сборок релизов.