Обновите команду разработчиков с переписанной историей репозитория Git, удалив большие файлы
У меня есть git-репо с очень большими двоичными файлами. Они мне больше не нужны, и меня не волнует возможность извлекать файлы из предыдущих коммитов. Итак, чтобы уменьшить размер репо, я хочу полностью удалить двоичные файлы из истории.
После поиска в Интернете я пришел к выводу, что мой лучший (только?) Вариант - это использовать git-filter-branch
:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_1.zip big_2.zip etc.zip' HEAD
Пока это кажется хорошим подходом?
Предполагая, что ответ - да, у меня есть другая проблема, с которой приходится бороться. Руководство Git имеет это предупреждение:
ПРЕДУПРЕЖДЕНИЕ! Переписанная история будет иметь разные имена объектов для всех объектов и не будет сходиться с исходной ветвью. Вы не сможете легко перемещать и распространять переписанную ветвь поверх оригинальной ветки. Пожалуйста, не используйте эту команду, если вы не знаете всех последствий, и избегайте ее использования в любом случае, если для решения вашей проблемы будет достаточно простого коммита. (Обратитесь к разделу "ВОССТАНОВЛЕНИЕ ОТ ИБАЗОВОГО РЕБАЗА" в git-rebase(1) для получения дополнительной информации о перезаписи опубликованной истории.)
У нас есть удаленное репо на нашем сервере. Каждый разработчик подталкивает и тянет от этого. На основании приведенного выше предупреждения (и моего понимания того, как git-filter-branch
работает), я не думаю, что смогу бежать git-filter-branch
на моей локальной копии, а затем нажмите изменения.
Итак, я предварительно планирую пройти следующие шаги:
- Скажите всем моим разработчикам, чтобы они фиксировали, давили и прекратили работать немного.
- Войдите на сервер и запустите фильтр на центральном репо.
- Попросите всех удалить свои старые копии и снова клонировать с сервера.
Это звучит правильно? Это лучшее решение?
4 ответа
Да, ваше решение будет работать. У вас также есть другой вариант: вместо того, чтобы делать это в центральном репо, запустите фильтр на вашем клоне и затем нажмите его обратно с git push --force --all
, Это заставит сервер принимать новые ветки из вашего хранилища. Это заменяет только шаг 2; другие шаги будут такими же.
Если ваши разработчики хорошо разбираются в Git, то им, возможно, не придется удалять свои старые копии; например, они могут получить новые пульты и перебазировать ветки своих тем в зависимости от ситуации.
Ваш план хорош (хотя было бы лучше выполнить фильтрацию на голом клоне вашего хранилища, а не на центральном сервере), но предпочтительнее git-filter-branch
Вы должны использовать мой BFG Repo-Cleaner, более быструю и простую альтернативу git-filter-branch
разработан специально для удаления больших файлов из репозитория Git.
Загрузите Java jar (требуется Java 6 или выше) и выполните эту команду:
$ java -jar bfg.jar --strip-blobs-bigger-than 1MB my-repo.git
Любой BLOB-объект размером более 1 МБ (которого нет в вашем последнем коммите) будет полностью удален из истории вашего репозитория. Вы можете использовать git gc
чтобы убрать мертвые данные:
$ git gc --prune=now --aggressive
BFG обычно в 10-50 раз быстрее, чем бег git-filter-branch
и варианты приспособлены вокруг этих двух общих вариантов использования:
- Удаление сумасшедших больших файлов
- Удаление паролей, учетных данных и других личных данных
Если вы не заставите своих разработчиков повторно клонировать, вполне вероятно, что им удастся перетащить большие файлы обратно. Например, если они аккуратно склеятся с новой историей, которую вы создадите, а затем случитесь с git merge
из локальной ветки проекта, которая не была перебазирована, родители коммита слияния будут включать ветку проекта, которая в конечном итоге указывает на всю историю, которую вы стерли git filter-branch
,
Ваше решение не завершено. Вы должны включить --tag-name-filter cat
в качестве аргумента для фильтрации ветви, так что теги, которые содержат большие файлы, также изменяются. Вы также должны изменить все ссылки, а не просто HEAD, так как фиксация может быть в нескольких ветвях.
Вот некоторый лучший код:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_1.zip big_2.zip etc.zip' --tag-name-filter cat -- --all
У Github есть хорошее руководство: https://help.github.com/articles/remove-sensitive-data