Удаление конфиденциальных данных из истории Git: от теории к практике
Привет, Хабр!
Эта статья — мой первый опыт, и я буду рад конструктивной критике. В ней я разберу на реальном примере, как полностью удалить файлы или папки из истории коммитов Git. Это может понадобиться, если вы случайно закоммитили чувствительную информацию (ключи, пароли, конфиги).
Важное предупреждение: Переписывание истории — опасная операция. Её нельзя применять к публичным веткам, с которыми работают другие люди. Это вызовет рассинхронизацию их репозиториев. Всегда сначала меняйте пароли/ключи, если есть возможность! Переписывать историю стоит только если вы точно знаете, что делаете, и работаете в одиночку или договорились с командой.
Инструмент: git filter-repo
Раньше для таких задач часто использовали git filter-branch
или BFG
, но сейчас сообщество рекомендует более современный и безопасный инструмент — git filter-repo
. Его нужно установить отдельно. Всю документацию и способы установки можно найти на официальной странице проекта.
Постановка задачи
Создадим учебный сценарий: мы уже несколько раз закоммитили файлы, а потом осознали, что папка 0.1/
не должна была попасть в репозиторий. Просто добавить её в .gitignore
и удалить недостаточно — она останется в истории предыдущих коммитов. Наша цель — стереть её оттуда полностью.
Практическая часть: шаг за шагом
1. Подготовка и осознание проблемы
Сначала мы создали файлы и папки, прокоммитили их, а затем добавили 0.1/
в .gitignore
. Однако, как видно на скриншоте, простое добавление в .gitignore
не удаляет файл из индекса Git. Он продолжает отслеживаться.
Команда для удаления файла из индекса (staging area), но сохранения его на диске:
git rm -r --cached "0.1"
После этого папка 0.1
перестаёт отслеживаться, и последующие коммиты её не включают. Но она навсегда остаётся в истории прошлых коммитов.
2. Переписывание истории с помощью git filter-repo
Вот команда, которая полностью вычищает папку 0.1
из всей истории Git:
git filter-repo --path "0.1" --invert-paths --force
--path "0.1"
— указывает, с каким путём работать.--invert-paths
— инвертирует условие: удалить все коммиты, затрагивающие этот путь, а не оставить их.--force
— принудительный запуск, так какfilter-repo
отказывается работать в обычном режиме с существующего клона. (По сути, он создаёт новый репозиторий из старого).
Результат: После выполнения команды история переписывается. Все коммиты, в которых фигурировала папка 0.1
, исчезают или изменяются (их хэши меняются!). При этом сама папка 0.1
остаётся у вас на диске как неотслеживаемый файл, что и требовалось.
Выводы и полезные ссылки
git filter-repo
— мощный и рекомендуемый инструмент для очистки истории.Переписывание истории — это
--force
-пуш и потенциальные проблемы для команды. Всегда предупреждайте коллег!Если скомпрометированы пароли или ключи — лучше сразу поменять их, а не полагаться на удаление из Git.
Дополнительные материалы для изучения:
Официальная документация
git filter-repo
— очень подробная и полезная.Книга "Pro Git" — must-read для глубокого понимания работы Git.
Надеюсь, мой опыт будет вам полезен. Буду рад вопросам и комментариям!