Обновите команду разработчиков с переписанной историей репозитория 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 на моей локальной копии, а затем нажмите изменения.

Итак, я предварительно планирую пройти следующие шаги:

  1. Скажите всем моим разработчикам, чтобы они фиксировали, давили и прекратили работать немного.
  2. Войдите на сервер и запустите фильтр на центральном репо.
  3. Попросите всех удалить свои старые копии и снова клонировать с сервера.

Это звучит правильно? Это лучшее решение?

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

Другие вопросы по тегам