Миграция Git-репозиториев на SHA-256: приключение с подмодулями
SHA-256 как формат объектов доступен в Git начиная с версии 2.42. Автор заметки с иронией перечисляет «преимущества» перехода: реальной выгоды для безопасности нет — старого доброго SHA-1dc вполне достаточно; идентификаторы объектов становятся ещё длиннее и неудобнее; зато можно щегольнуть модной хеш-функцией. А ещё новый формат вызывает несварение у большинства сторонних инструментов вроде jujutsu/gitoxide и Eclipse/JGit — что, конечно же, никакое не преимущество.
Простой случай
Для репозитория без подмодулей рецепт находится легко (разумеется, не в документации Git, а на разрозненных страницах в сети). В старом репозитории выполняется git fast-export --all > export, а в новом — git init --object-format sha256 и затем git fast-import < ../old/export.
Проблема в том, что как только в репозитории появляются подмодули, всё разваливается. При добавлении SHA-1-подмодуля в SHA-256-репозиторий старый идентификатор просто дополняется нулями, а fast-import падает с ошибкой «object not found» и вываливает отчёт о сбое.
Недокументированное спасение
Существуют опции --rewrite-submodules-from и --rewrite-submodules-to, позволяющие переписать идентификаторы подмодулей из старого хеша в новый. Но вся документация к ним — несколько абзацев без единого примера и без упоминания сопутствующих команд. Автор честно признаётся: без предварительного понимания это выглядит как бессмысленная каша.
Рабочая последовательность такова. Сначала экспортируется подмодуль с сохранением меток: git fast-export --export-marks=marks --all > export. Важный нюанс: если репозиторий когда-либо ссылался на коммит, выпавший из текущих веток (например, после force-push), такие «осиротевшие» объекты придётся указать явно. Затем подмодуль импортируется в новый SHA-256-репозиторий, также с сохранением меток. И только после этого основной репозиторий переносится с указанием пары опций --rewrite-submodules-from и --rewrite-submodules-to, где слева удобнее всего ставить имя самого подмодуля.
Бонус: Forgejo и подписи
Forgejo настойчиво предлагает удалить репозиторий и создать новый. Но если есть доступ к серверу, миграцию можно провести на месте — автор предупреждает, что это «крайне хак» и сломает все ссылки на конкретные коммиты (теги при этом сохраняются). После переноса bare-репозитория нужно вручную прописать в базе данных object_format_name = "sha256", после чего запустить в панели администрирования синхронизацию веток, тегов и хуков. В результате сохраняются задачи, вики, pull-request'ы и проекты.
Наконец, переподписать все коммиты можно через git rebase --exec с --gpg-sign — правда, для подмодулей это не годится. Впрочем, достаточно одной подписи на вершине ветки: структура Git сама образует цепочку доверия.
Источник: Lobsters
Комментарии
Войдите, чтобы комментировать.