Как перенести все URL-адреса в свойствах svn: externals в репозитории?

Мы находимся в процессе перемещения наших репозиториев SVN с одной машины на другую, и с ней появится новое доменное имя для нового репо. Проблема заключается в том, что внутри репозитория существует множество ссылок svn: externals на другие проекты в репозитории. Так, например, у нас есть projectA, который имеет свойства svn: externals:

external/libraryA svn://oldserver.net/repo/libraryA
external/libraryB svn://oldserver.net/repo/libraryB

... и так далее. Все URL ссылаются на это конкретное доменное имя, поэтому его можно легко проанализировать. Выучив мой урок, я перенучу эти URL-адреса как "svn://localhost/", но мне нужно найти способ просмотреть историю репозитория и переписать все старые URL-адреса, чтобы мы все еще могли проверить более старые версии этих проектов, не нарушая связей.

Как мне это сделать?

Ответ 1

Как вы указали, что вы все еще хотите проверить старые версии, единственным решением является "переписать" всю историю (решение D упомянуто ранее).

Для этого вам необходимо:

1) Дамп содержимого всего репозитория с помощью svnadmin dump:

$ svnadmin dump /path/to/repos > original-dumpfile
* Dumped revision 0.
* Dumped revision 1.
* Dumped revision 2.
* Dumped revision 3.

2) Отредактируйте файл дампа, чтобы изменить URL-адреса svn: externals. Это самая сложная часть. Предполагая, что репозиторий содержит двоичные данные, открытие файла дампа в текстовом редакторе скорее всего приведет к повреждению файла дампа. У меня были хорошие впечатления, используя так называемый "hex-editor", например Freeware Hex Editor XVI32

3) Создайте новый репозиторий и загрузите в него измененный файл дампа:

$ svnadmin create newrepos
$ svnadmin load newrepos < modified-dumpfile

Для получения дополнительной информации, вам также может быть интересна эта ссылка:
http://svnbook.red-bean.com/en/1.1/ch05s03.html

ПРИМЕЧАНИЕ. Subversion 1.5 фактически добавила поддержку относительных URL-адресов в свойство svn: externals, которое может точно предотвратить такие проблемы в будущем:
http://subversion.tigris.org/svn_1.5_releasenotes.html#externals

Ответ 2

Я использовал бы SvnDumpTool. Он имеет именно то, что вы ищете:

svndumptool transform-prop svn:externals "(\S*) (|-r ?\d* ?)http://oldserver.net(/\S*)" "\2\3 \1" source.dumpfile source-fixed-externals.dumpfile

Это фиксирует каждый внешний вид subversion 1.5 format и использует относительные URL-адреса.

Итак, svn: externals like:

external/libraryA svn://oldserver.net/repo/libraryA

стали:

 /repo/libraryA external/libraryA

с использованием корневых относительных URL-адресов сервера.

Ответ 3

Мне пришлось переместить 12 рабочих копий через 9 пользователей и 4 развертывания. Это было простое изменение, заменив домен IP, т.е. thing.domain.net -> 192.168.0.1

Ожидая svn relocate вести себя как описано (пересекайте вложенные внешние элементы), я написал простую инструкцию DOS для запуска в каждом месте:

for /D %G in (*) do ( cd ./%G & svn relocate http://thing.domain.net http://192.168.0.1 & cd ..)

Это не сработало, как ожидалось, только переместив родительский WC.

Мое решение состояло в том, чтобы изменить сами репозитории (я использовал Tortoise Repo Browser), чтобы изменить расположение внешних. После этого изменения обновление для перемещенного родителя было всем, что требовалось, чтобы привести все в соответствие.

Вероятно, было бы неплохо заставить всех пользователей Tortoise очистить свою историю URL-адресов, чтобы они не совершали непреднамеренно выполнение операций с использованием старого URL-адреса (он все еще существует в поиске DNS):

Settings->Saved Data->URL history->Clear

Ответ 4

Я редактировал файл дампа с помощью vi, но мне пришлось использовать переключатель "-b" для редактирования в двоичном режиме, так что любые символы, которые могут быть интерпретированы как окончание строк, не преобразуются.

например. vi -b filename.dump

Кроме того, я обнаружил, что, если длина URL-адреса изменяется, существуют также длины строк, которые также необходимо было изменить. Например, рассмотрим запись, которая выглядит так:

Node -path: trunk/src/include

Node -kind: dir

Node -action: change

Длина рекламного содержимого: 192

Контент-длина: 192

К13

SVN: внешние

V 156

MGL_ABC svn://имя_сервера/dir1/dir2

MGL_DEF svn://имя_сервера/dir1/dir3

При изменении этих URL-адресов, если длина строки изменяется, вам также нужно изменить "192", "192" и "156", чтобы соответствовать новой длине. Мне было трудно вычислить абсолютную длину, но легко найти дифференциал.
Например, предположим, что URL 1 становится короче на 3 символа, а URL 2 становится короче на 4 символа. Затем вам придется отбросить "7" от каждого из этих трех строк длины строки.

Ответ 5

Вы можете:

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

b) найдите время, чтобы написать script, который находит свойства в текущей (старой ревизии) рабочей копии и изменяет URL-адреса там, не совершая их. ИЛИ:

c) обратите внимание на ревизию (-s), где вы отметили новые значения свойств, проверьте старую версию и просто объедините эти изменения (которые влияют только на свойства) в вашу рабочую копию.

d) или, возможно, использовать svndump для дампа данных репозитория, строки - заменить URL-адрес в дампе, а затем восстановить его.. Я бы не дал вам никакой гарантии, что это даже работает; -)

Ответ 6

Все мои внешние были в каталогах с именем flow. Я исправил URL-адреса в своих внешних файлах с помощью этого однострочного (bash shell):

for p in $(find -maxdepth 4 -name flow); do svn ps svn:externals "$(svn pg svn:externals $p/.. | perl -pe 's/^(\w+) svn\+ssh.*thing\.domain\.net(.*)/$2 $1/')" $p/..; done