Управление большими двоичными файлами с помощью Git

StackOverflow https://stackoverflow.com/questions/540535

Вопрос

Я ищу мнения о том, как обращаться с большими двоичными файлами, от которых зависит мой исходный код (веб-приложение).Сейчас мы обсуждаем несколько вариантов:

  1. Скопируйте двоичные файлы вручную.
    • Плюсы:Не уверен.
    • Против:Я категорически против этого, так как это увеличивает вероятность ошибок при настройке нового сайта/переносе старого.Создает еще одно препятствие, которое нужно преодолеть.
  2. Управляйте ими всеми с помощью Гит.
    • Плюсы:Удаляет возможность «забыть» скопировать важный файл.
    • Против:Раздувает репозиторий и снижает гибкость управления кодовой базой, проверками, клонами и т. д.займет довольно много времени.
  3. Отдельные репозитории.
    • Плюсы:Извлечение/клонирование исходного кода происходит как никогда быстро, а изображения правильно архивируются в собственном репозитории.
    • Против:Устраняет простоту наличия единственный и неповторимый Git-репозиторий проекта.Это, конечно, знакомит с некоторыми другими вещами, о которых я не думал.

Каковы ваши впечатления/мысли по этому поводу?

Также:Есть ли у кого-нибудь опыт работы с несколькими репозиториями Git и управления ими в одном проекте?

Файлы представляют собой изображения для программы, которая генерирует PDF-файлы с этими файлами.Файлы не будут меняться очень часто (как в течение многих лет), но они очень важны для программы.Программа не будет работать без файлов.

Это было полезно?

Решение

Если программа не будет работать без файлов, то разделение их на отдельный репозиторий — плохая идея.У нас есть большие наборы тестов, которые мы разбиваем в отдельный репозиторий, но это действительно «вспомогательные» файлы.

Однако вы можете управлять файлами в отдельном репозитории, а затем использовать git-submodule чтобы разумным образом вовлечь их в свой проект.Таким образом, у вас по-прежнему будет полная история всего вашего источника, но, насколько я понимаю, у вас будет только одна соответствующая редакция вашего подмодуля изображений.А git-submodule Это средство должно помочь вам обеспечить соответствие правильной версии кода правильной версии изображений.

Вот хороший введение в подмодули из книги Git.

Другие советы

Я обнаружил git-приложение недавно, что я считаю потрясающим.Он был разработан для эффективного управления большими файлами.Я использую его для своих коллекций фотографий/музыки (и т. д.).Разработка git-приложения идет очень активно.Содержимое файлов можно удалить из репозитория Git, Git отслеживает только иерархию дерева (через символические ссылки).Однако, чтобы получить содержимое файла, после извлечения/пересылки необходим второй шаг, например:

$ git annex add mybigfile
$ git commit -m'add mybigfile'
$ git push myremote
$ git annex copy --to myremote mybigfile ## This command copies the actual content to myremote
$ git annex drop mybigfile ## Remove content from local repo
...
$ git annex get mybigfile ## Retrieve the content
## or to specify the remote from which to get:
$ git annex copy --from myremote mybigfile

Доступно множество команд, и на веб-сайте есть отличная документация.Пакет доступен на Дебиан.

Другое решение, с апреля 2015 года: Хранилище больших файлов Git (LFS) (с помощью GitHub).

Оно использует git-lfs (видеть git-lfs.github.com) и протестировано на поддерживающем его сервере: lfs-тест-сервер:
Вы можете хранить метаданные только в репозитории git, а большой файл — в другом месте.

https://cloud.githubusercontent.com/assets/1319791/7051226/c4570828-ddf4-11e4-87eb-8fc165e5ece4.gif

Посмотри на мерзавец, чувак это расширение Git для разумного хранения больших двоичных файлов в репозитории Git.

Вы хотели бы иметь его в качестве подмодуля, но вам не придется беспокоиться о том, что с репозиторием будет сложно работать.Один из примеров использования — хранение образов виртуальных машин в Git.

На самом деле я не видел более высоких показателей сжатия, но в моих репозиториях нет действительно больших двоичных файлов.

Ваш пробег может отличаться.

Вы также можете использовать толстяк.Мне нравится, что это зависит только от стандартного Python и rsync.Он также поддерживает обычный рабочий процесс Git со следующими понятными командами:

git fat init
git fat push
git fat pull

Кроме того, вам необходимо вернуть файл .gitfat в свой репозиторий и изменить свои .gitattributes, чтобы указать нужные расширения файлов. git fat справляться.

Вы добавляете двоичный файл, используя обычный git add, что, в свою очередь, вызывает git fat на основе ваших правил gitattributes.

Наконец, у него есть то преимущество, что место, где фактически хранятся ваши двоичные файлы, может быть общим для всех репозиториев и пользователей и поддерживает что угодно. rsync делает.

ОБНОВЛЯТЬ:Не используйте git-fat, если вы используете мост Git-SVN.В конечном итоге двоичные файлы будут удалены из вашего репозитория Subversion.Однако если вы используете чистый репозиторий Git, он работает прекрасно.

Я бы использовал подмодули (как Пэт Нотц) или два разных репозитория.Если вы слишком часто изменяете свои двоичные файлы, я бы постарался свести к минимуму влияние очистки истории огромного репозитория:

Несколько месяцев назад у меня была очень похожая проблема:~21 ГБ файлов MP3, несекретных (плохие имена, плохие идентификаторы id3, не знаю, нравится мне этот файл MP3 или нет...), реплицированных на трех компьютерах.

Я использовал внешний жесткий диск с основным репозиторием Git и клонировал его на каждый компьютер.Затем я начал классифицировать их привычным образом (толкать, тянуть, сливать...много раз удаляя и переименовывая).

В итоге у меня осталось всего ~6 ГБ файлов MP3 и ~83 ГБ в каталоге .git.я использовал git-write-tree и git-commit-tree создать новый коммит без предков коммита и запустить новую ветку, указывающую на этот коммит.«Журнал git» для этой ветки показал только один коммит.

Затем я удалил старую ветку, оставил только новую ветку, удалил журналы ссылок и запустил «git prune»:после этого мои папки .git весили всего около 6 ГБ...

Вы можете время от времени «очищать» огромный репозиторий таким же образом:Ваш «git clone» будет быстрее.

По моему мнению, если вы собираетесь часто изменять эти большие файлы или собираетесь создавать много git clone или git checkout, то вам следует серьезно подумать об использовании другого репозитория Git (или, возможно, другого способа доступа к этим файлам).

Но если вы работаете так же, как мы, и если ваши бинарные файлы не часто изменяются, то первое клонирование/извлечение будет долгим, но после этого оно должно быть настолько быстрым, насколько вы хотите (учитывая, что ваши пользователи продолжают использовать первый клонированный репозиторий, они имел).

Решение, которое я хотел бы предложить, основано на бесхозных ветвях и небольшом злоупотреблении механизмом тегов, в дальнейшем называемом *Двоичное хранилище сиротских тегов. (ОТАБС)

ТЛ;ДР 01.12.2017 Если вы можете использовать LFS от github или какой-либо другой третьей стороны, вам обязательно следует это сделать.Если не можете, то читайте дальше.Имейте в виду, это решение является хаком и к нему следует относиться соответственно.

Желательные свойства OTABS

  • это чистый мерзавец и только мерзавец решение - оно выполняет свою работу без какого-либо стороннего программного обеспечения (например, git-annex) или сторонней инфраструктуры (например, LFS от github).
  • он хранит двоичные файлы эффективно, т.е.это не раздувает историю вашего репозитория.
  • git pull и git fetch, включая git fetch --all все еще эффективная полоса пропускания, т.е.не все большие двоичные файлы по умолчанию извлекаются с удаленного компьютера.
  • это работает на Окна.
  • он хранит все в один репозиторий git.
  • это позволяет удаление устаревших бинарных файлов (в отличие от bup).

Нежелательные свойства ОТАБС

  • это делает git clone потенциально неэффективно (но не обязательно, в зависимости от вашего использования).Если вы развернете это решение, вам, возможно, придется посоветовать своим коллегам использовать git clone -b master --single-branch <url> вместо git clone.Это потому, что git clone по умолчанию буквально клонирует весь репозиторий, включая вещи, на которые вы обычно не хотели бы тратить свою пропускную способность, например коммиты без ссылок.Взято из СО 4811434.
  • это делает git fetch <remote> --tags полоса пропускания неэффективна, но не обязательно неэффективна память.Вы всегда можете посоветовать своим коллегам не использовать его.
  • вам придется периодически использовать git gc трюк, позволяющий очистить ваш репозиторий от любых файлов, которые вам больше не нужны.
  • это не так эффективно, как буп или git-большие файлы.Но он, соответственно, больше подходит для того, что вы пытаетесь сделать, и более готов.Вероятно, у вас возникнут проблемы с сотнями тысяч небольших файлов или с файлами размером в несколько гигабайт, но читайте дальше, чтобы найти обходные пути.

Добавление двоичных файлов

Прежде чем начать, убедитесь, что вы зафиксировали все свои изменения, ваше рабочее дерево обновлено и ваш индекс не содержит незафиксированных изменений.Возможно, было бы неплохо перенести все ваши локальные ветки на удаленный компьютер (GitHub и т. д.) на случай, если произойдет какая-либо катастрофа.

  1. Создайте новую ветку-сироту. git checkout --orphan binaryStuff сделает свое дело.В результате создается ветка, которая полностью отделена от любой другой ветки, и первый коммит, который вы сделаете в этой ветке, не будет иметь родителя, что сделает его корневым коммитом.
  2. Очистите свой индекс, используя git rm --cached * .gitignore.
  3. Сделайте глубокий вдох и удалите все рабочее дерево, используя rm -fr * .gitignore.Внутренний .git каталог останется нетронутым, поскольку * подстановочный знак не соответствует ему.
  4. Скопируйте файл VeryBigBinary.exe или VeryHeavyDirectory/.
  5. Добавьте его и зафиксируйте.
  6. Теперь это становится сложнее — если вы отправите его на удаленный компьютер как ветку, все ваши разработчики загрузят его при следующем вызове. git fetch засорение их соединения.Вы можете избежать этого, поместив тег вместо ветки.Это все равно может повлиять на пропускную способность и хранилище файловой системы вашего коллеги, если у него есть привычка печатать. git fetch <remote> --tags, но читайте дальше, чтобы найти обходной путь.Идите вперед и git tag 1.0.0bin
  7. Нажмите свой потерянный тег git push <remote> 1.0.0bin.
  8. Чтобы вы никогда случайно не отправили свою двоичную ветку, вы можете удалить ее. git branch -D binaryStuff.Ваш коммит не будет помечен для сбора мусора, поскольку на него указывает потерянный тег. 1.0.0bin достаточно, чтобы сохранить его в живых.

Проверка двоичного файла

  1. Как мне (или моим коллегам) вернуть VeryBigBinary.exe в текущее рабочее дерево?Если ваша текущая рабочая ветка, например, master, вы можете просто git checkout 1.0.0bin -- VeryBigBinary.exe.
  2. Это не удастся, если у вас нет потерянного тега. 1.0.0bin загружено, и в этом случае вам придется git fetch <remote> 1.0.0bin заранее.
  3. Вы можете добавить VeryBigBinary.exe в твоего магистра .gitignore, чтобы никто из вашей команды случайно не засорил основную историю проекта бинарным файлом.

Полное удаление двоичного файла

Если вы решите полностью удалить VeryBigBinary.exe из своего локального репозитория, удаленного репозитория и репозиториев ваших коллег, вы можете просто:

  1. Удалить потерянный тег на пульте дистанционного управления git push <remote> :refs/tags/1.0.0bin
  2. Удалить потерянный тег локально (удалит все остальные теги, на которые нет ссылок) git tag -l | xargs git tag -d && git fetch --tags.Взято из ТАК 1841341 с небольшой модификацией.
  3. Используйте трюк git gc, чтобы локально удалить уже ненужный коммит. git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@".Он также удалит все остальные коммиты, на которые нет ссылок.Взято из ТАК 1904860
  4. Если возможно, повторите трюк с git gc на удаленном компьютере.Это возможно, если вы размещаете свой репозиторий самостоятельно, но может быть невозможно с некоторыми поставщиками git, такими как github, или в некоторых корпоративных средах.Если вы пользуетесь хостингом у провайдера, который не предоставляет вам доступ по SSH к пульту, просто оставьте это.Вполне возможно, что инфраструктура вашего провайдера в свое время очистит ваш неиспользуемый коммит.Если вы работаете в корпоративной среде, вы можете посоветовать своему ИТ-специалисту запускать задание cron по сбору мусора с вашего пульта примерно раз в неделю.Независимо от того, сделают они это или нет, это не повлияет на вашу команду с точки зрения пропускной способности и хранилища, если вы посоветуете своим коллегам всегда git clone -b master --single-branch <url> вместо git clone.
  5. Всем вашим коллегам, желающим избавиться от устаревших потерянных тегов, достаточно выполнить шаги 2–3.
  6. Затем вы можете повторить шаги 1–8 из Добавление двоичных файлов чтобы создать новый потерянный тег 2.0.0bin.Если вы беспокоитесь о том, что ваши коллеги будут печатать git fetch <remote> --tags на самом деле ты можешь назвать его еще раз 1.0.0bin.Это гарантирует, что в следующий раз они получат все старые теги. 1.0.0bin не будут иметь ссылки и будут помечены для последующей сборки мусора (с использованием шага 3).Когда вы пытаетесь перезаписать тег на пульте дистанционного управления, вам придется использовать -f так: git push -f <remote> <tagname>

Послесловие

  • OTABS не затрагивает ваш master или любые другие ветки исходного кода/разработки.Хэши коммитов, вся история и небольшой размер этих веток не затрагиваются.Если вы уже заполнили историю исходного кода двоичными файлами, вам придется очистить ее как отдельную часть работы. Этот сценарий может быть полезно.

  • Подтверждено, что он работает в Windows с git-bash.

  • Хорошей идеей является применение набор стандартных трюков сделать хранение двоичных файлов более эффективным.Частая работа git gc (без каких-либо дополнительных аргументов) заставляет git оптимизировать базовое хранилище ваших файлов с помощью двоичных дельт.Однако, если ваши файлы вряд ли останутся одинаковыми от фиксации к фиксации, вы можете вообще отключить двоичные дельты.Кроме того, поскольку нет смысла сжимать уже сжатые или зашифрованные файлы, такие как .zip, .jpg или .crypt, git позволяет отключить сжатие базового хранилища.К сожалению, это параметр «все или ничего», влияющий и на ваш исходный код.

  • Возможно, вы захотите создать скрипты для частей OTABS, чтобы обеспечить более быстрое использование.В частности, шаги 2–3 сценария из Полное удаление двоичных файлов в update git перехватчик может дать убедительную, но, возможно, опасную семантику для git fetch («извлечь и удалить все, что устарело»).

  • Возможно, вы захотите пропустить шаг 4 из Полное удаление двоичных файлов хранить полную историю всех двоичных изменений на удаленном компьютере за счет раздувания центрального репозитория.Локальные репозитории со временем останутся компактными.

  • В мире Java это решение можно объединить с maven --offline чтобы создать воспроизводимую автономную сборку, полностью хранящуюся в вашем системе контроля версий (с maven это проще, чем с gradle).В мире Golang возможно использовать это решение для управления вашим GOPATH вместо go get.В мире Python это можно объединить с virtualenv для создания автономной среды разработки, не полагаясь на серверы PyPi для каждой сборки с нуля.

  • Если ваши двоичные файлы изменяются очень часто, например артефакты сборки, возможно, было бы хорошей идеей создать сценарий решения, которое хранит 5 самых последних версий артефактов в потерянных тегах. monday_bin, tuesday_bin, ..., friday_bin, а также потерянный тег для каждого выпуска. 1.7.8bin 2.0.0bin, и т. д.Вы можете вращать weekday_bin и ежедневно удаляйте старые двоичные файлы.Таким образом, вы получаете лучшее из двух миров:ты держишь весь историю вашего исходного кода, но только соответствующий история ваших бинарных зависимостей.Также очень легко получить двоичные файлы для данного тега. без получение всего исходного кода со всей его историей: git init && git remote add <name> <url> && git fetch <name> <tag> должен сделать это за вас.

SVN, кажется, обрабатывает двоичные изменения более эффективно, чем Git.

Мне пришлось выбрать систему управления версиями документации (файлы JPEG, файлы PDF и файлы .odt).Я только что протестировал добавление файла JPEG и четыре раза поворот его на 90 градусов (чтобы проверить эффективность двоичных дельт).Репозиторий Git вырос на 400%.Репозиторий SVN вырос всего на 11%.

Похоже, что SVN гораздо эффективнее работает с двоичными файлами.

Поэтому мой выбор — Git для исходного кода и SVN для двоичных файлов, таких как документация.

git clone --filter из Git 2.19 + мелкие клоны

Эта новая опция может в конечном итоге стать окончательным решением проблемы двоичных файлов, если разработчики Git и GitHub сделают ее достаточно удобной для пользователя (что они, возможно, и делают). для подмодулей до сих пор не достигнуто например).

Фактически он позволяет получать на сервере только те файлы и каталоги, которые вам нужны, и был представлен вместе с расширением удаленного протокола.

Благодаря этому мы могли бы сначала выполнить поверхностное клонирование, а затем автоматизировать выборку больших двоичных объектов с помощью системы сборки для каждого типа сборки.

Уже даже есть --filter=blob:limit<size> что позволяет ограничить максимальный размер извлекаемого объекта.

Я предоставил минимальный подробный пример того, как эта функция выглядит: Как клонировать только подкаталог репозитория Git?

Я ищу мнения о том, как обращаться с большими двоичными файлами, от которых зависит мой исходный код (веб-приложение).Каковы ваши впечатления/мысли по этому поводу?

Я лично столкнулся сбои синхронизации с Git с некоторыми из моих облачных хостов после того, как двоичные данные моих веб-приложений были изменены выше отметки 3 ГБ.я считал Очиститель репозиториев BFT в то время, но это было похоже на хакерство.С тех пор я начал просто хранить файлы за пределами Git, вместо этого используя специально созданные инструменты например Amazon S3 для управления файлами, управления версиями и резервного копирования.

Есть ли у кого-нибудь опыт работы с несколькими репозиториями Git и управления ими в одном проекте?

Да. Темы Хьюго в основном управляются таким образом.Это немного странно, но свою работу выполняет.


Мое предложение состоит в том, чтобы выбрать правильный инструмент для работы.Если это для компании и вы управляете своей кодовой линией на GitHub, заплатите деньги и используйте Git-LFS.В противном случае вы можете изучить более творческие варианты, такие как децентрализованный, зашифрованный хранение файлов с использованием блокчейна.

Дополнительные варианты, которые следует рассмотреть, включают в себя Минио и s3cmd.

Посмотри на камлистор.На самом деле он не основан на Git, но я считаю его более подходящим для того, что вам нужно делать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top