Содержание
Проблематика
Будем честны, все мы хотя бы раз коммитили файл с секретами, забывали добавить что-то в .gitignore
или после git add .
видели в коммите здоровый файл, которому бы место в Release-ах или в хранилище артефактов. Но суть в том, что git помнит все, и даже если мы удалили файл, переписали его, засквошили все коммиты, то все равно с помощью того же git reflog
можно откопать старые данные. Поэтому расмотрим пару интересных программ для исправления этих ошибок.
git-filter-repo
Самый простой и при этом наиболее полный из всех существующих методов чистки репозиториев. Это всего навсего один1 питонячий файл, который можно просто скачать, но всегда можно воспользоваться и пакетным менеджером:
# Macosbrew install git-filter-repo
# Archsudo pacman -S git-filter-repo
# Python!pip install git-filter-repo
Все! теперь мы можем зайти в любую репу и проверить, что filter-repo работает:
git filter-repo --analyze
Мы увидим что-то вроде:
Processed 8 blob sizesProcessed 1 commitsWriting reports to .git/filter-repo/analysis...done.
Это удобная штука, которая может подсказать, что в дальнейшем стоит почистить или правильно ли сработала предыдущая команда. Отчет - это просто набор текстовых файлов, которые можно просмотреть.
Общий подход
git-filter-repo
- очень мощная утилита, пользоваться которой нужно очень острожно. Ведь любая из выполняемых команд по сути изменяет хэши коммитов, и требует push --force
в оригинальную репу. Поэтому общий флоу работы такой:
- Клонируем свежую копию нашей репы (желательно в новую папку, чтобы случайно не напортачить чего-то в старой) и заходим в нее:
git clone <URL оригинальной репы> some_dircd some_dir
- Запускаем команды необходимые в данный момент:
git filter-repo <MAGIC>
- В результате у нас будет удален
origin
, поэтому его надо будет заново добавить:
git remote add origin <URL оригинальной репы>
- Пушим новые изменения:
git push --force --mirror origin

Лишние файлы
Самое типичное, с чем часто приходится сталкиваться.
TLDR
git clone <repo_url> <repo_dir>cd <repo_dir>git filter-repo --invert-paths --path <file_path>git remote add origin <repo_url>git push --force --mirror origin
Подробно
Рассмотрим на примере. Есть небольшой репозиторий, в историю которого по ошибке закрался файл .env
, с чувствительными данными. Наш коллега удалил его, добавил в .gitignore, но если откатиться к старому коммиту, то он все равно есть:

Для удаления из истории одного файла выполняем такую команду:
git filter-repo --invert-paths --path <путь до файла от корня git репы>

Лишние папки
Все аналогично инструкции по удалению лишних файлов.
Просто при указании --path
пишем путь до директории.
Секреты
TBD
Сноски
-
Файл, конечно, один, но все же рекомендую пользоваться пакетными менеджерами, а то мало ли. ↩