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

ВНИМАНИЕ! Переписанная история будет иметь разные имена объектов для всех объектов и не будет сходиться с исходной ветвью. Вы не сможете легко нажимать и распространять переписанную ветку поверх исходной ветки. Пожалуйста, не используйте эту команду, если вы не знаете о всех последствиях, и избегайте ее использования в любом случае, если достаточно простой фиксации, чтобы исправить вашу проблему. (См. Раздел "ВОССТАНОВЛЕНИЕ ОТ РЕЖИМА ОБНОВЛЕНИЯ UPSTREAM" в разделе git -rebase (1) для получения дополнительной информации о перезаписи опубликованной истории.)

У нас есть удаленное репо на нашем сервере. Каждый разработчик подталкивает и извлекает из него. Основываясь на вышеприведенном предупреждении (и мое понимание того, как работает git-filter-branch), я не думаю, что смогу запустить git-filter-branch в своей локальной копии, а затем нажимать изменения.

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

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

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

Ответ 1

Да, ваше решение будет работать. У вас также есть другой вариант: вместо того, чтобы делать это на центральном репо, запустите фильтр на вашем клоне, а затем нажмите его обратно с помощью git push --force --all. Это заставит сервер принимать новые ветки из вашего репозитория. Это заменяет только шаг 2; другие шаги будут одинаковыми.

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

Ответ 2

Ваш план хорош (хотя было бы лучше выполнить фильтрацию на голой клоне вашего репозитория, а не на центральном сервере), но вместо git-filter-branch вы должны использовать мой BFG Repo-Cleaner, более быстрая и простая альтернатива git-filter-branch, разработанная специально для удаления больших файлов из Git repos.

Загрузите банку Java (требуется Java 6 или выше) и выполните следующую команду:

$ java -jar bfg.jar  --strip-blobs-bigger-than 1MB  my-repo.git

Любой блок размером более 1 МБ (который не находится в вашей последней фиксации) будет полностью удален из истории вашего хранилища. Затем вы можете использовать git gc для очистки мертвых данных:

$ git gc --prune=now --aggressive

BFG обычно на 10-50 раз быстрее, чем запуск git-filter-branch, и параметры настраиваются в этих двух общих случаях использования:

  • Удаление Сумасшедших больших файлов
  • Удаление Паролей, учетных данных и других личных данных

Ответ 3

Если вы не заставляете своих разработчиков повторно клонировать его, вероятно, что им удастся перетащить большие файлы. Например, если они тщательно сплайсируют новую историю, которую вы создадите, а затем выполните git merge с ветвь локального проекта, которая не была переустановлена, родители слияния будут включать ветку проекта, которая в конечном итоге указывает на всю историю, которую вы удалили с помощью git filter-branch.

Ответ 4

Ваше решение не является полным. Вы должны включить --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