Подтвердить что ты не робот

Как я могу исправить репозиторий с одной разбитой ревизией?

У моего домашнего сервера был сбой жесткого диска.

Как только я понял, что происходит диск, я вошел в систему и сделал прямую копию моего репозитория, содержащего несколько проектов.

Однако, поскольку диск не работает, одна из ревизий нарушена:

$ 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, но я не уверен, на что можно положиться. Обратите внимание, что он не регистрирует, что он успешно удалил любую ревизию.

Обновить. У меня была другая идея: скопировать новые файлы ревизий из копии с аварийным копированием в 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

Теперь у меня закончились идеи.

4b9b3361

Ответ 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.

Yay!