Иногда возникает необходимость удалить из git папку/файл, но проблема в том, что они остаются в истории и папка .git может весить очень много.
BFG Repo-Cleaner
Существует утилита BFG Repo-Cleaner, которая может быстро выпилить из истории и кеша лишние папки/файлы.
На сервере требуется установленная Java
Загрузка утилиты
Версия на момент написания статьи 1.13.0
wget https://repo1.maven.org/maven2/com/madgag/bfg/1.13.0/bfg-1.13.0.jar && mv bfg-1.13.0.jar bfg.jar
Очистка истории
Для удаления всех файлов с расширением *.jpg
:
java –jar bfg.jar --delete-files '*.jpg' --no-blob-protection
Если не указать опцию --no-blob-protection
, может возникнуть ошибка «содержимое выше может быть удалено из других коммитов, но так как «защищенные» коммиты все еще используют его, оно все еще будет существовать в вашем репозитории». Так как по умолчанию HEAD ветка защищена.
На примере папки images
java -jar bfg.jar --delete-folders images
Переиндексация и очистка кеша
После очистки истории утилита предложит выполнить команду для переиндексации. Запускаем.
git reflog expire --expire=now --all && git gc --prune=now --aggressive
И пушим все в удаленный репозиторий.
git push
В итоге работе утилиты выпиливается вся история коммитов, связанная с удаляемой папкой и почистится кеш. Папка .git значительно уменьшается в размерах.
git filter-branch
Пример использования:
git filter-branch --prune-empty --index-filter "git rm -rf --cached --ignore-unmatch .env bitrix" -- --all
После выполнения команды файл .env
и каталог bitrix
будут полностью удалены из истории проекта, опция --prune-empty
также удалит образовавшиеся пустые коммиты, которые были связаны с этими файлами/каталогами.
Поскольку filter-branch
формирует бэкап, для возможности отката, то для полной очистки потребуется удалить .git/refs/original/
и почистить логи .git/logs/
:
rm -rf .git/refs/original
rm -rf .git/logs/
История проекта будет фактически переписана заново, а значит потребуется заново клонировать репозиторий.
Очистка от мусора:
git reflog expire --expire=now --all && git gc --prune=now --aggressive
Отправка новой истории веток и тегов на сервер:
git push origin --force --all
git push origin --force --tags
Резльтаты
Различия между BFG Repo-Cleaner и git filter-branch заключаются в том, что с помощью git filter-branch можно удалить файлы из заданного каталога, а также сам каталог, а с помощью BFG Repo-Cleaner нет. BFG Repo-Cleaner позволяет удалять файлы по имени без указания пути и сразу из всех веток, а в git filter-branch нужно указывать из каких веток нужно удалить.
Плюсы
BFG Repo-Cleaner | git filter-branch |
---|---|
Удаление из всех веток по маске | Удаление каталогов |
Быстродействие | Указание пути в файлам |
Указание ветвей для удаления |
Минусы
BFG Repo-Cleaner | git filter-branch |
---|---|
Нельзя удалить каталоги | Очень медленно работает |
Нельзя указать путь к файлам |