skip to content
Архитектура в курилке
Bob Ross

Чистим историю Git-а

/ чтиво на 2 минуты

Содержание

Проблематика

Будем честны, все мы хотя бы раз коммитили файл с секретами, забывали добавить что-то в .gitignore или после git add . видели в коммите здоровый файл, которому бы место в Release-ах или в хранилище артефактов. Но суть в том, что git помнит все, и даже если мы удалили файл, переписали его, засквошили все коммиты, то все равно с помощью того же git reflog можно откопать старые данные. Поэтому расмотрим пару интересных программ для исправления этих ошибок.

git-filter-repo

Github

Самый простой и при этом наиболее полный из всех существующих методов чистки репозиториев. Это всего навсего один1 питонячий файл, который можно просто скачать, но всегда можно воспользоваться и пакетным менеджером:

Terminal window
# Macos
brew install git-filter-repo
# Arch
sudo pacman -S git-filter-repo
# Python!
pip install git-filter-repo

Все! теперь мы можем зайти в любую репу и проверить, что filter-repo работает:

Terminal window
git filter-repo --analyze

Мы увидим что-то вроде:

Processed 8 blob sizes
Processed 1 commits
Writing reports to .git/filter-repo/analysis...done.

Это удобная штука, которая может подсказать, что в дальнейшем стоит почистить или правильно ли сработала предыдущая команда. Отчет - это просто набор текстовых файлов, которые можно просмотреть.

Общий подход

git-filter-repo - очень мощная утилита, пользоваться которой нужно очень острожно. Ведь любая из выполняемых команд по сути изменяет хэши коммитов, и требует push --force в оригинальную репу. Поэтому общий флоу работы такой:

  1. Клонируем свежую копию нашей репы (желательно в новую папку, чтобы случайно не напортачить чего-то в старой) и заходим в нее:
Terminal window
git clone <URL оригинальной репы> some_dir
cd some_dir
  1. Запускаем команды необходимые в данный момент:
Terminal window
git filter-repo <MAGIC>
  1. В результате у нас будет удален origin, поэтому его надо будет заново добавить:
Terminal window
git remote add origin <URL оригинальной репы>
  1. Пушим новые изменения:
Terminal window
git push --force --mirror origin
Ошибка

Лишние файлы

Самое типичное, с чем часто приходится сталкиваться.

TLDR

Terminal window
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, но если откатиться к старому коммиту, то он все равно есть:

Файл остается

Для удаления из истории одного файла выполняем такую команду:

Terminal window
git filter-repo --invert-paths --path <путь до файла от корня git репы>
Удаляем один файл

Лишние папки

Все аналогично инструкции по удалению лишних файлов.

Просто при указании --path пишем путь до директории.

Секреты

TBD

Сноски

  1. Файл, конечно, один, но все же рекомендую пользоваться пакетными менеджерами, а то мало ли.