Как я могу исправить хранилище с одной сломанной ревизией?
У моего домашнего сервера был сбой жесткого диска.
Как только я понял, что диск работает, я вошел в систему и сделал прямую копию своего хранилища, которое содержит несколько проектов.
Однако, поскольку диск вышел из строя, одна из ревизий повреждена:
$ svnadmin verify master/
[...]
* Verified revision 820.
* Verified revision 821.
* Verified revision 822.
svnadmin: No such revision 823
master/db/revs/
а также master/db/revprops/
каталоги действительно не содержат никаких файлов, называемых 823
, так что эта ревизия отсутствует (не работает). Есть последующие изменения (которые я действительно хочу сохранить!) В master/
хранилище собирается до ревизии № 947.
Сегодня я получил свою самую последнюю резервную копию (!), Которая включает эту ревизию. Я хотел бы "исцелить" сломанный репозиторий в master/
путем исправления отсутствующей ревизии, поскольку она более поздняя, чем резервная копия.
Я удостоверился, что загрузил файл дампа во вновь созданный репозиторий с той же версией, что и скопированный в master/
так что это все старый "линейный" формат 3.
Я попробовал очевидное, чтобы просто скопировать файл 823
из резервной копии db/revs/
а также db/revprops/
справочники:
$ cp repos/db/revs/0/823 master/db/revs/
$ cp repos/db/revprops/0/823 master/db/revprops/
Каталог repos/
содержит репозиторий, который был загружен из резервной копии. Теперь я получаю:
$ svnadmin verify master/
[...]
* Verified revision 821.
* Verified revision 822.
svnadmin: /build/buildd/subversion-1.6.12dfsg/subversion/libsvn_delta/compose_delta.c:165: search_offset_index: Assertion `offset < ndx->offs[ndx->length]' failed.
Aborted
Что не очень обнадеживает. Я пробовал различные другие svnadmin
команды, но ни одна не порадовала верификатора.
Моя следующая идея состояла в том, чтобы отменить копирование и начать со "свежей" копии испорченного репозитория, затем выгрузить ревизии после 823 и объединить с резервной копией. Но это не представляется возможным, я не могу выбросить ревизии после пропущенной:
$ svnadmin dump -r 824 master/ >r824.dmp
svnadmin: No such revision 823
Обратите внимание, что это не поможет сделать дамп "инкрементным", в надежде, что он должен притвориться, что мир начался с ревизии 824 и просто перейти оттуда:
$ svnadmin dump --incremental -r 824:947 master/ > dump.txt
svnadmin: No such revision 823
Это записывает вывод в dump.txt
, но я не уверен, можно ли на это положиться. Обратите внимание, что он не регистрирует, что он успешно сбросил любую ревизию.
Обновление: у меня была другая идея: скопировать более новые файлы ревизии из crash-disk-copy в master/
в резервную копию, чтобы предоставить "отсутствующий хвост":
$ for a in $(seq 910 947) ; do cp master/db/revs/$a repos/db/revs ; cp master/db/revprops/$a repos/db/revprops/ ; echo $a ; done
Тем не менее, это, похоже, ничего не делает, но повреждает целевой репозиторий:
$ svnadmin verify repos/
[...]
* Verified revision 907.
* Verified revision 908.
* Verified revision 909.
svnadmin: Corrupt representation '907 21815 45 30922 158d3e72732f45bf6f02919b22fc899a'
svnadmin: Malformed representation header
Теперь у меня закончились идеи.
1 ответ
Я решил это.
Решение было (конечно) очевидным, как только я это понял.
У меня было это:
master/
Копия поврежденного репозитория с ревизией 0..947 с физически отсутствующими файлами ревизии 823.repos/
: Хранилище, загруженное из резервной копии (файла дампа), охватывающее ревизию 0..910.
Решение было просто сбросить с master/
Начиная с версии 911 и далее. Это было возможно без каких-либо ошибок, что, как я понимаю, означает, что ни одна из ревизий в диапазоне 911..947 напрямую не зависела от состояния в ревизии 823 или чего-то подобного:
$ svnadmin dump --incremental -r 911:947 master/ > tail.txt
* Dumped revision 911.
* Dumped revision 912.
* Dumped revision 913.
[...]
* Dumped revision 947.
В любом случае, затем просто примените дамп к хранилищу из резервной копии:
$ cat tail.txt | svnadmin load repos/
[lots of commits]
И теперь у меня полная история восстановлена, проблем нет
$ svnadmin verify repos/
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
[...]
* Verified revision 945.
* Verified revision 946.
* Verified revision 947.
Ура!