Git LFS (Large File Storage)
Узнайте, как Git LFS хранит большие бинарные файлы за пределами истории репозитория с помощью лёгких указателей. Установка и команды.
Что такое Git LFS
Git LFS (Large File Storage) — это расширение с открытым исходным кодом для Git, которое хранит большие бинарные файлы — видео, наборы данных, дизайн-ресурсы, игровую графику — за пределами истории Git. Вместо того чтобы хранить в репозитории файл весом 500 МБ, Git LFS помещает туда небольшой текстовый указатель, а само содержимое хранит в отдельном LFS-хранилище. В результате клонирование остаётся быстрым, а репозиторий — маленьким, даже если проект использует гигабайты ресурсов.
В этой главе рассматривается: когда стоит использовать LFS, как установить расширение и настроить отслеживание файлов, что содержит указатель, повседневные команды, блокировка файлов для бинарников без поддержки слияния, а также типичные подводные камни.
Почему большие файлы вредят Git
Git создан для текста и хранит полную историю каждого файла. Кроме того, Git хранит файлы по содержимому: при изменении бинарника Git обычно сохраняет полностью новую копию, а не небольшую дельту, поскольку бинарные файлы плохо поддаются диффу. Несколько коммитов с большим бинарным файлом — и каждый клон должен навсегда скачивать все его версии, даже те, что никому не нужны. История раздувается, клонирование замедляется, а push-операции завершаются по таймауту. Git LFS обходит эту проблему, версионируя маленький указатель вместо тяжёлого содержимого.
Прибегайте к LFS, когда файлы большие и меняются со временем — исходники дизайна, скомпилированные ресурсы, наборы данных, аудио и видео. Если файлы вообще не нуждаются в версионировании, лучше исключите их из репозитория полностью с помощью .gitignore.
Установка
Сначала установите Git, а затем — расширение LFS. На большинстве систем Git LFS поставляется отдельно (brew install git-lfs, apt install git-lfs или установщик с сайта git-lfs.com). Активируйте его один раз на машине:
git lfs installUpdated Git hooks.
Git LFS initialized.Укажите LFS, какие файлы нужно отслеживать, задав паттерны. Это записывает правила в .gitattributes:
git lfs track "*.psd"
git lfs track "*.mp4"
git add .gitattributes.gitattributes должен быть закоммичен, чтобы все участники команды получили одинаковые правила. Теперь соответствующие файлы будут автоматически обрабатываться через LFS. Коммит и push выполняются как обычно:
git add design.psd
git commit -m "Add hero design source"
git pushGit загружает указатель в репозиторий, а бинарное содержимое — в LFS-хранилище. При клонировании Git LFS подключается автоматически и скачивает реальное содержимое для текущего коммита.
Как выглядит указатель
В репозитории отслеживаемый файл заменяется маленьким текстовым указателем, который содержит хэш и размер содержимого:
version https://git-lfs.github.com/spec/v1
oid sha256:9af1c2a3b4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f7
size 471859200Три строки — это версия спецификации, SHA-256-идентификатор объекта содержимого (oid) и размер в байтах. Именно столько места файл занимает в истории Git — несколько сотен байт вне зависимости от размера ресурса. Когда кто-то извлекает файл, Git LFS использует этот указатель для получения реального содержимого по требованию.
Основные команды
| Команда | Описание |
|---|---|
git lfs install | Включает LFS для текущего пользователя (выполняется один раз). |
git lfs track "<pattern>" | Начинает управлять файлами, соответствующими паттерну, через LFS. |
git lfs untrack "<pattern>" | Прекращает управлять паттерном. |
git lfs ls-files | Выводит список файлов, отслеживаемых LFS. |
git lfs status | Показывает, какие LFS-файлы проиндексированы или изменены. |
git lfs pull | Скачивает LFS-содержимое для текущего рабочего дерева. |
git lfs fetch | Скачивает LFS-объекты без обновления рабочего дерева. |
git lfs prune | Удаляет старые неиспользуемые LFS-файлы из локального хранилища. |
git lfs migrate | Переписывает существующую историю, перемещая большие файлы в LFS. |
Чтобы убедиться, чем именно управляет LFS, выведите список отслеживаемых файлов:
git lfs ls-files9af1c2a3b4 * design.psd
1c0ffee5d6 * intro.mp4Каждая строка содержит короткий идентификатор объекта, * — если реальное содержимое присутствует локально (- — если извлечён только указатель), и путь к файлу.
Блокировка файлов
Бинарные файлы вроде .psd или .fbx нельзя слить — если два человека редактируют один и тот же файл, изменения одного из них будут потеряны. Git LFS добавляет блокировку файлов, чтобы участник команды мог заявить права на файл перед его редактированием:
git lfs lock images/banner.psd
git lfs locks
git lfs unlock images/banner.psdОтметьте паттерн как блокируемый в .gitattributes, чтобы файл был доступен только для чтения до момента блокировки — это защищает от случайных правок:
git lfs track "*.psd" --lockableДля работы блокировки требуется поддержка на стороне сервера (GitHub и GitLab её предоставляют).
Перенос существующих файлов в LFS
Отслеживание распространяется только на файлы, закоммиченные после добавления правила. Файлы, которые уже есть в истории, остаются в Git как полные бинарники. Чтобы перенести их, перепишите историю с помощью git lfs migrate:
git lfs migrate import --include="*.mp4"Это переписывает коммиты и изменяет их хэши — согласуйте действия с командой и выполните force-push после завершения, как при любой перезаписи истории.
Что нужно знать
- Необходима поддержка на стороне сервера. GitHub, GitLab и Bitbucket предоставляют LFS, нередко с квотами на объём хранилища и трафик, за превышение которых может взиматься плата. Репозиторий может исчерпать LFS-квоту, даже если его Git-размер остаётся небольшим.
- У всех участников должно быть установлено расширение. Любой, кто клонирует репозиторий, должен иметь Git LFS, иначе вместо реального файла он увидит текст указателя. В этом случае достаточно установить LFS и выполнить
git lfs pull. - Указатели — обычные объекты Git. Ветвление, слияние и просмотр диффов указателя работают стандартно; LFS подменяет реальное содержимое только в момент извлечения файла.