Как сделать копию удалённого репозитория Subversion

jetxee

2008-08-13

Материал распространяется на условиях Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.

Резервная копия репозитория Subversion, находящегося на локальной машине, делается обычно так:

$ svnadmin dump /путь/к/репозиторию > мой-дамп

Всё просто, достаточно иметь прямой доступ к каталогу с репозиторием.

Увы, для удалённых репозиториев, управляемых кем-то другим (например, на code.google.com), такой фокус не проходит. А как-то беспокойно на душе, когда нет своей копии... Зато проходят фокусы с созданием локального «зеркала» (копии) удалённого репозитория, с которым потом можно делать всё, что угодно.

Фокусов здесь можно сделать целых два.

Фокус первый

Содержимое удалённого SVN-репозитория можно легко перенести в локальный SVK-репозиторий. SVK — это система управления версиями, использующая хранилище SVN. То есть, фактически, всего лишь надстройка над Subversion.

Итак, чтобы фокус получился, для начала удаляем локальный SVK-репозиторий (конечно, если в нём нет ничего ценного):

$ rm -rf ~/.svk

Далее:

$ svk ls URL-удалённого-SVN-репозитория

(утвердительно отвечаем на все вопросы; svk создаёт локальный репозиторий с копией изменений из удалённого SVN-репозитория).

Теперь осталось сделать резервную копию:

$ svnadmin dump -r2:HEAD ~/.svk/local > мой-дамп

(создаём dump всех изменений, игнорируя первые две ревизии SVK-репозитория, к нашим делам отношения не имеющие).

Узнал я про такой фокус здесь.

Фокус второй

SVK пользоваться легко, но, к сожалению, SVK не сохраняет номера ревизий SVN. Поэтому для точного зеркалирования репозитория он не годится.

Тут на помощь может прийти другой инструмент: svnsync, появившийся в Subversion начиная с версии 1.4. svnsync предназначен для одностороннего зеркалирования репозиториев SVN (то есть для создания репозиториев-клонов, предназначенных только для чтения).

Для начала создадим новый репозиторий, куда будем всё копировать. Это описано в документации Subversion:

$ svnadmin create /путь/к/новому/локальному/репозиторию

Не используйте в качестве зеркала уже существующие репозитории! svnsync может полностью перезаписать их содержимое.

После этого обозначим переменными MASTERSVN и COPYSVN адреса исходного репозитория и нового локального:

$ MASTERSVN=URL-удалённого-SVN-репозитория
$ COPYSVN=file:///путь/к/новому/локальному/репозиторию

После этого делаем пустой «хук» в локальном репозитории-зеркале:

$ cd /путь/к/новому/локальному/репозиторию
$ echo "#!/bin/sh" > hooks/pre-revprop-change
$ chmod 755 hooks/pre-revprop-change

Далее инициализируем репозиторий-зеркало:

$ svnsync init ${COPYSVN} ${MASTERSVN}

при этом будут установлены ряд свойств репозитория-зеркала, в нём же будет сохранён адрес удалённого репозитория.

Чтобы начать передачу данных (синхронизовать репозиторий-зеркало с удалённым), следует выполнить такую команду:

$ svnsync --non-interactive sync ${COPYSVN}

В некоторых случаях (например, если предыдущая синхронизация оборвалась аварийно) svnsync может жаловаться на то, что не может заблокировать репозиторий-зеркало. В этих случаях помогает такая команда:

$ svn propdel svn:sync-lock --revprop -r 0  ${COPYSVN}

Поскольку я обычно синхронизую репозитории автоматически, по crontab, в скрипте для синхронизации репозиториев пишу так:

if [ $(svn proplist --revprop -r 0 ${COPYSVN} | \
 grep sync-lock | wc -l) -ne 0 ] ; then
 sleep 15
 svn propdel svn:sync-lock --revprop -r 0 ${COPYSVN}
fi

Этому фокусу я научился по статьям using svnsync и svnsync: mirror your svn repository. Пока доволен.

P.S. Недавно в блогах на runix.org проскакивало, в блоге Strannick-а, как копировать гиперссылки, используя два буфера обмена. Правой кнопкой мыши щелкнуть по ссылке и копировать адрес ссылки (в буфер GNOME), а потом выделить текст ссылки мышью (помещается в буфер X Window). Чтобы вставить: Shift-Ins (Ctrl-V) для адреса, щелчок средней мыши для текста ссылки. Мне понравилось! Если потренироваться — довольно удобно.