Как удалить старые коммиты, не влияя на историю - PullRequest
2 голосов
/ 03 июля 2019

Мне нужно удалить коммиты, сделанные 1 год назад, потому что они содержат конфиденциальные данные, которые должны быть удалены.

Я использовал BFG Repo-Cleaner , и мне удалось почти все удалить, но есть некоторые очень старые коммиты, которые не удаляются .

Я постараюсь написать пример; История GIT выглядит так

  • C -> секретные файлы не существуют
  • B -> секретные файлы удалены
  • A -> были добавлены секретные файлы

( A самый старый и C самый новый коммит)

И это то, что мне нужно ( B больше не существует , но более поздние коммиты не затрагиваются):

  • C -> секретные файлы не существуют
  • A -> были добавлены секретные файлы

Я работаю в большой команде, поэтому, если нет другого выбора, я бы хотел избежать использования git push -f.

Каков наилучший способ добиться этого?

Большое спасибо.

(редактирование)

Причина этого в том, что мы регулярно проверяем репозиторий, в котором зафиксирован фиксация A как уязвимость.

Мы сделали коммит B, если мы удалили все учетные и секретные файлы, и проблема в том, что сканирование также обнаруживает коммит B как «проблему безопасности».

Нас просят удалить коммит B для прохождения сканирования.

1 Ответ

2 голосов
/ 03 июля 2019

TL; DR

  • вы должны переписать коммит А, чтобы в первую очередь не содержать конфиденциальный файл
  • вы должны использовать git push -f
  • вы еще не закончили: вы все равно должны очистить историю на сервере

Переписать коммит А и всю историю

Это должно быть то, что bfg сделал для вас. Я предполагаю, что вы запустили что-то вроде bfg --delete-files <sensitive-file>. Это должно было создать совершенно новую историю, где <sensitive-file> никогда не существовало: коммиты, которые добавили или изменили его, а также другие файлы, должны быть переписаны без этого файла. Коммиты, которые только коснулись его, должны исчезнуть, поскольку теперь они будут пустыми коммитами.

Итак, теперь у вас есть коммит A ', копия A без <sensitive-file>. Остальная часть истории переписана как ее наследники: C 'и т. Д.

Чтобы убедиться, что это произошло правильно, запустите эту команду как в старой, так и в новой изолированной программной среде, обновленной bfg:

git log --all <sensitive-file>

Вы должны увидеть коммиты, затрагивающие чувствительный файл в исходном репо, но не выводимые в новом. Таким образом вы можете быть уверены, что файл действительно удален из истории.

Вы должны использовать git push -f

Sha1 коммита Git - это криптографическая подпись коммита, всех его метаданных (коммитер, дата, комментарий и т. Д.), Всего его содержимого и всей его истории.

Если вы измените какой-либо один аспект фиксации: дату, комментарии, содержимое или любой другой аспект любого из его предков, криптографическая подпись изменится по определению.

Так что единственный путь вперед - это git push -f.

Вы, вероятно, еще не закончили

Но подождите, после выполнения git push -f на сервере останутся копии старой истории. Смотрите здесь для GitHub: Если вы нажали на GitHub, будет слишком поздно, даже если вы принудительно оттолкнете его на одну секунду позже . По-видимому, единственный действительно безопасный способ удалить конфиденциальный файл из репозитория GitHub - это удалить его и воссоздать новый, содержащий только чистую историю, которую вы хотите сохранить. Существуют и другие решения, но ваш пробег может отличаться - подробности в сообщении.

Если вы используете другой или частный Git-сервер, не забудьте принудительно выполнить сборку мусора и следуйте дальнейшим рекомендациям по Удалите конфиденциальные файлы и их коммиты из истории Git

...