Решение, которое я хотел бы предложить, основано на ветвях-сиротах и небольшом злоупотреблении механизмом тегов, далее именуемом * Двоичное хранилище тегов-сирот (OTABS)
TL; DR 12-01-2017 Если вы можете использовать LFS github или какую-либо другую стороннюю компанию, во что бы то ни стало, вам следует. Если не можете, тогда читайте дальше. Имейте в виду, это решение взломано и должно рассматриваться как таковое.
Желательные свойства ОТАБС
- это решение pure git и git only - оно выполняет свою работу без какого-либо стороннего программного обеспечения (например, git-annex) или сторонней инфраструктуры (например, LFS на github). ).
- эффективно хранит двоичные файлы , т. Е. Не раздувает историю вашего хранилища.
git pull
и git fetch
, включая git fetch --all
, по-прежнему с эффективностью полосы пропускания , т. Е. По умолчанию не все большие двоичные файлы извлекаются из пульта.
- работает на Windows .
- хранит все в одном git-репозитории .
- позволяет удалять устаревших двоичных файлов (в отличие от bup).
Нежелательные свойства ОТАБС
- делает
git clone
потенциально неэффективным (но не обязательно, в зависимости от вашего использования). При развертывании этого решения вам, возможно, придется посоветовать коллегам использовать git clone -b master --single-branch <url>
вместо git clone
. Это потому, что git clone по умолчанию буквально клонирует весь репозиторий, включая вещи, на которые вы обычно не хотите тратить свою пропускную способность, например, нефиксированные коммиты. Взято из SO 4811434 .
- делает пропускную способность
git fetch <remote> --tags
неэффективной, но не обязательно неэффективной для хранения. Вы всегда можете посоветовать своим коллегам не использовать его.
- вам придется периодически использовать трюк
git gc
для очистки вашего хранилища от любых файлов, которые вам больше не нужны.
- это не так эффективно, как bup или git-bigfiles . Но это соответственно больше подходит для того, что вы пытаетесь сделать, и больше готово. Вы, вероятно, столкнетесь с проблемами, связанными с сотнями тысяч небольших файлов или файлами размером в гигабайты, но читайте дальше для обходных путей.
Добавление двоичных файлов
Перед тем, как начать, убедитесь, что вы зафиксировали все свои изменения, ваше рабочее дерево обновлено, и ваш индекс не содержит никаких незафиксированных изменений. Может быть хорошей идеей передать все локальные филиалы на удаленный компьютер (github и т. Д.) На случай, если произойдет какая-либо катастрофа.
- Создать новую сиротскую ветвь.
git checkout --orphan binaryStuff
сделает свое дело. В результате получается ветвь, которая полностью отключена от любой другой ветки, и первый коммит, который вы сделаете в этой ветке, не будет иметь родителя, что сделает его корневым.
- Очистите свой индекс, используя
git rm --cached * .gitignore
.
- Сделайте глубокий вдох и удалите все рабочее дерево, используя
rm -fr * .gitignore
. Внутренний каталог .git
останется нетронутым, поскольку подстановочный знак *
ему не соответствует.
- Скопируйте в свой VeryBigBinary.exe или VeryHeavyDirectory /.
- Добавьте и&& зафиксируйте.
- Теперь все становится сложнее - если вы вставите его в пульт как ветку, все ваши разработчики загрузят его в следующий раз, когда они вызовут
git fetch
, забив свое соединение. Вы можете избежать этого, нажав метку вместо ветки. Это все еще может повлиять на пропускную способность вашего коллеги и хранилище файловой системы, если они имеют привычку набирать git fetch <remote> --tags
, но читайте дальше, чтобы обойти это. Иди и git tag 1.0.0bin
- Нажми свою сиротскую метку
git push <remote> 1.0.0bin
.
- Точно так, что вы никогда не нажмете свою ветку двоичных файлов случайно, вы можете удалить ее
git branch -D binaryStuff
. Ваш коммит не будет помечен для сборки мусора, потому что для его поддержки достаточно тега-сироты, указывающего на него 1.0.0bin
.
Проверка двоичного файла
- Как я (или мои коллеги) извлекаю VeryBigBinary.exe в текущее рабочее дерево? Если ваша текущая рабочая ветка, например, master, вы можете просто
git checkout 1.0.0bin -- VeryBigBinary.exe
.
- Это не удастся, если у вас не загружен потерянный тег
1.0.0bin
, в этом случае вам придется заранее git fetch <remote> 1.0.0bin
.
- Вы можете добавить
VeryBigBinary.exe
в .gitignore
вашего мастера, чтобы никто в вашей команде не загрязнил основную историю проекта двоичным файлом.
Полное удаление двоичного файла
Если вы решите полностью удалить VeryBigBinary.exe из своего локального хранилища, своего удаленного хранилища и хранилищ вашего коллеги, вы можете просто:
- Удалить потерянный тег на пульте
git push <remote> :refs/tags/1.0.0bin
- Локальное удаление тега-сироты (удаляет все остальные теги, на которые нет ссылок)
git tag -l | xargs git tag -d && git fetch --tags
. Взято из SO 1841341 с небольшими изменениями.
- Используйте хитрость git gc, чтобы удалить ваш теперь не имеющий ссылки коммит локально.
git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@"
. Это также удалит все другие не связанные ссылки. Взято из SO 1904860
- Если возможно, повторите трюк с git gc на пульте. Это возможно, если вы самостоятельно размещаете свой репозиторий, и это может быть невозможно с некоторыми провайдерами git, такими как github или в некоторых корпоративных средах. Если вы пользуетесь хостингом у провайдера, который не предоставляет доступ по ssh к удаленному, просто оставьте его. Вполне возможно, что инфраструктура вашего провайдера очистит вашу ссылку без привязки в свое приятное время. Если вы находитесь в корпоративной среде, вы можете посоветовать своим ИТ-специалистам запускать мусорное задание cron, собирая ваш пульт один раз в неделю или около того. Независимо от того, влияют они или нет, это не повлияет на вашу команду с точки зрения пропускной способности и хранилища, если вы советуете своим коллегам всегда
git clone -b master --single-branch <url>
вместо git clone
.
- Всем вашим коллегам, которые хотят избавиться от устаревших тегов-сирот, нужно только применить шаги 2-3.
- Затем можно повторить шаги 1-8 из Добавление двоичных файлов , чтобы создать новый потерянный тег
2.0.0bin
. Если вы беспокоитесь о том, что ваши коллеги набирают git fetch <remote> --tags
, вы можете назвать его еще раз 1.0.0bin
. Это будет гарантировать, что в следующий раз, когда они выберут все теги, старый 1.0.0bin
не будет иметь ссылки и помечен для последующей сборки мусора (с помощью шага 3). Когда вы пытаетесь перезаписать тег на пульте, вы должны использовать -f
, например: git push -f <remote> <tagname>
Послесловие
OTABS не касается вашего мастера или любых других исходных кодов / ветвей разработки. Хеши коммитов, вся история и небольшой размер этих веток не затрагиваются. Если вы уже раздули свою историю исходного кода с помощью двоичных файлов, вам придется очистить ее как отдельную часть работы. Этот скрипт может быть полезен.
Подтверждено для работы в Windows с git-bash.
Рекомендуется применить набор стандартных трюков , чтобы сделать хранение бинарных файлов более эффективным. Частое выполнение git gc
(без каких-либо дополнительных аргументов) позволяет git оптимизировать базовое хранилище ваших файлов с помощью двоичных дельт. Однако, если ваши файлы вряд ли останутся похожими на коммит, вы можете полностью отключить двоичные дельты. Кроме того, поскольку нет смысла сжимать уже сжатые или зашифрованные файлы, такие как .zip, .jpg или .crypt, git позволяет отключить сжатие основного хранилища. К сожалению, это параметр «все или ничего», влияющий и на ваш исходный код.
Возможно, вы захотите написать сценарии частей OTABS, чтобы обеспечить более быстрое использование. В частности, сценарии 2-3 из Полное удаление бинарных файлов в update
ловушку git могут дать убедительную, но, возможно, опасную семантику для git fetch («извлекать и удалять все, что устарело») .
Возможно, вы захотите пропустить шаг 4 из Полное удаление двоичных файлов , чтобы сохранить полную историю всех двоичных изменений на пульте дистанционного управления за счет увеличения объема центрального хранилища. Локальные хранилища со временем останутся сухими.
В мире Java можно объединить это решение с maven --offline
, чтобы создать воспроизводимую автономную сборку, полностью сохраненную в вашем контроле версий (это проще с maven, чем с gradle). В мире Голанга возможно использовать это решение для управления 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>
должен сделать это за вас.