Можно ли отменить постоянное удаление файла?

Мой коллега попытался навсегда удалить файл (Diff.java) из истории нашего репозитория GitHub.

У него были веские причины хотеть сделать это, однако, похоже, что-то пошло не так, как мы, похоже, потеряли довольно много файлов, которые были заменены эквивалентными файлами с суффиксом .REMOVED.git-id, Например ivy-2.2.0.jar -> ivy-2.2.0.jar.REMOVED.git-id,

Мне удалось восстановить основную ветку разработки, так как у меня получилась копия локально. Однако есть много исторических веток для линий разработки и тегов для выпусков, которые теперь, похоже, не работают так, как описано выше.

Я понимаю, что он запустил процесс, похожий на:

$ git clone --mirror git://example.com/some-big-repo.git
$ java -jar bfg-1.12.3.jar --strip-biggest-blobs 500 some-big-repo
$ cd some-big-repo
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
$ git push

$ cd ..
$ java -jar bfg-1.12.3.jar --delete-files Diff.java some-big-repo
$ cd some-big-repo
$ git push

Я предполагаю, что процесс был разрушительным, и нет никакого способа восстановиться, если у нас не будет чистого зеркала где-то до того, как это произошло. Кто-нибудь может подтвердить или дать совет?

1 ответ

Решение

Это был шаг, который удалил все эти старые банки:

$ java -jar bfg-1.12.3.jar --strip-biggest-blobs 500 some-big-repo

... как автор BFG, я огорчен, осознав, --strip-biggest-blobs 500 не так ясно, как я думал. Команда удаляет самые большие 500 файлов (то есть большие файлы или двоичные объекты больших объектов: "BLOB-объекты") из истории репозиториев. Мне было бы очень интересно узнать, что, по мнению пользователя, сделает этот шаг!

Это команда, от которой правильно избавились Diff.java:

$ java -jar bfg-1.12.3.jar --delete-files Diff.java some-big-repo

В инструкциях для BFG написано "Вы должны сделать резервную копию " своего хранилища перед запуском BFG, но, похоже, этого не произошло.

У вас все еще может быть шанс восстановить ваши старые ветки и теги, учитывая две вещи:

  1. Репозитории, в которых все еще доступны необработанные данные объекта. Это будет ваша локальная копия, и, возможно, также GitHub, так как они не работают git gc немедленно на их репозитории - объекты могут все еще быть вокруг, и на них могут даже ссылаться старые запросы на извлечение, если вы их используете. Я бы взял немедленный зеркальный клон вашего репозитория GitHub.
  2. Вам также нужны старые значения 'ref' (исходные идентификаторы ветвления и тэга). Вы можете найти их в журнале ваших локальных копий или в журналах вашего CI-сервера. BFG печатает старые и новые значения измененных ссылок в командной строке, но я думаю, что у вас все еще нет этого вывода. BFG в настоящее время не сохраняет этот вывод, но сохраняет object-id-map.old-new.txt файл под some-big-repo.bfg-report каталог при каждом запуске, содержащий старые и новые идентификаторы, для каждого изменения, которое он изменил. Там будет более одного из этих файлов, потому что BFG был запущен более одного раза. Используя эти файлы и изучив ваши текущие ссылки, вы должны иметь возможность вернуться через два прогона BFG, чтобы выяснить, какими были исходные идентификаторы фиксации ваших ссылок.

Ваш процесс восстановления, учитывая эти вещи, выглядит примерно так:

  • Возьмите --mirror клон вашего хранилища, скорее всего, по-прежнему будет содержать ваши старые объекты.
  • Проверьте, есть ли на самом деле эти объекты. Итак, предположим, что вы можете установить, что старый идентификатор для master было 686b0cd80ac328e060b80dda3c9dadb1e400134a, делать git cat-file -p 686b0cd80ac328e060b80dda3c9dadb1e400134a, Вы увидите сводку коммита, если объект все еще вокруг. если это не так, добавьте пульты для других репозиториев-кандидатов и попробуйте получить данные оттуда
  • Задавать master перейти к значению исходного коммита с помощью git update-ref: git update-ref refs/heads/master 686b0cd80ac328e060b80dda3c9dadb1e400134a

Повторите эти действия для всех других веток и тегов, которые вас интересуют - надеюсь, вы сможете написать это, удачи!

Другие вопросы по тегам