Скопируйте SVN-репозиторий на другой сервер и все равно сможете объединить - PullRequest
0 голосов
/ 23 февраля 2020

У меня есть транк на сервере A, и я хотел бы скопировать весь репозиторий SVN на сервер B, то есть создать там ту же транк. Затем я хотел бы иметь возможность объединить изменения, сделанные на сервере A в соединительной линии, в соединительную линию сервера B. Возможно ли это?

Я попытался с svn export, а затем import, но затем я не могу выполнить слияние. Есть идеи?

1 Ответ

1 голос
/ 24 февраля 2020

SVN не похож на git. Наличие отдельных репозиториев не позволяет вам легко объединять одно с другим.

Допустим, A и B являются идеальными копиями с HEAD, указывающим на ревизию 10000. Фред, сделанный Фредом для репо A, получит номер ревизии 10001. Затем Салли передает что-то еще для репо B, который также равен 10001. Вернуть эти репозитории в синхронизированном виде c с одинаковыми номерами ревизий невозможно.

Что возможно - это применение файлов исправлений. Допустим, компания Фреда сделала 100 коммитов в репозитории А. Фред может «экспортировать» эти коммиты с помощью сценария bash:

for rev in {1000..10100} do
  svn log -c $rev --diff > $rev.patch
done

Теперь у Фреда есть 100 файлов патчей, которые он может заархивировать и отправить это Салли. '

Теперь Салли нужно «объединить» те, в которых есть:

for patchfile in $(ls *.patch) do
  svn patch $patchfile
  svn ci
done

Будет много ручной работы по проверке всех изменений.


Ведение это на занятом проекте займет много работы, и, вероятно, не идеальная ситуация. Существует большая вероятность человеческой ошибки, и вам будет трудно отслеживать, какие ревизии были объединены, которые необходимо отправить и т. Д. c. Подумайте над тем, как / почему вы делаете это, и подумайте, подойдет ли вам один из этих подходов:

Ветви поставщика

Я предполагаю, что вы доставляете (или получаете) исходный код от другая компания. В этом случае, возможно, было бы неплохо задать вопрос, действительно ли вам нужны все детали всех коммитов в дублированном репозитории. Если вы рассматриваете исходный репозиторий как «поставщик», то рассматривайте каждое обновление дублированного репозитория как «интеграцию выпуска поставщика». Если между доставками существует 1000 коммитов, то вы можете доставить один гигантский коммит, представляющий новый релиз, и сделать фактическое svn merge этого. На самом деле, чтобы упростить задачу, просто сделайте periodi c svn export, чтобы создать простой архив без истории изменений.

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

Сначала настройте репозиторий:

# Start from an empty repository
# Initialize the repository with tags+branches directories
svn mkdir http://example.com/svn/awesomecode/tags
svn mkdir http://example.com/svn/awesomecode/branches

# Extract the contents of the source file.
tar -xf awesomecode_1.27.tar.xz

# Import the contents of that archive into your repository
svn import \
  awesomecode_1.27 \
  http://example.com/svn/awesomecode/upstream \
  -m "Importing upstream version 1.27"

# Tag the upstream version (optional)
svn copy \
  http://example.com/svn/awesomecode/upstream \
  http://example.com/svn/awesomecode/tags/upstream_1.27 \
  -m "Tagging upstream 1.27"

# Make a trunk to do your work in
svn copy \
  http://example.com/svn/awesomecode/upstream \
  http://example.com/svn/awesomecode/trunk

Когда мы отправляем обновление исходного кода, вы можете обновить свою ветку upstream / vendor:

# Checkout the upstream branch of the repository
svn checkout \
  http://example.com/svn/awesomecode/upstream \
  awesomecode

# Replace the old version
rm -rf awesomecode/*
tar -xf awesomecode_1.28.tar.xz \
  --strip-components=1 \
  --directory=awesomecode

# Commit the new version (also delete missing and add unversioned files)
cd awesomecode
svn delete $(svn status | sed -ne '/^!/p' | awk '{print $2}')
svn add $(svn status | sed -ne '/^?/p' | awk '{print $2}')
svn commit -m "Importing upstream version 1.28"

# Tag the new delivery:
svn copy \
  http://example.com/svn/awesomecode/upstream \
  http://example.com/svn/awesomecode/tags/upstream_1.28 \
  -m "Tagging upstream 1.28"

# Merge the delivery into your trunk
svn swtich ^/trunk
svn merge ^/upstream

Поскольку наши соединительные линии со временем расходятся, это объединение станет намного сложнее. Чтобы сделать это проще, рассмотрите возможность отправки нам некоторых ваших изменений. Мы рассмотрим исправления и добавим вещи, с которыми мы согласны, в нашу базу кода. Минимизация различий - это самый простой способ поддерживать управляемые слияния. Пожалуйста, отправьте один файл патча за коммит. Нам нужно проверять каждое изменение, и файл исправления из 20 000 строк не может быть просмотрен. Чтобы сгенерировать файлы исправлений из коммитов 5-10, сделайте следующее:

for rev in {5..10} do
  svn log -c $rev --diff > $rev.patch
done

Наиболее авторитетная литература по работе с ветвлением поставщика - SVN book


svn : externals

Еще одна причина, по которой вы захотите иметь один и тот же код в двух репозиториях, может заключаться в том, что вам просто нужен один и тот же код в двух разных проектах. Вот где svn:externals пригодится. Вы можете поддерживать общий код в репозитории external и просто иметь ссылку на него в своем проекте. Затем, если кто-то сделает коммит на ваш общий код, вы сможете воспользоваться им во всех проектах. Если ваш репозиторий поддерживает inte rnet, то вы можете подумать о том, чтобы ваш клиент интегрировал ваш исходный код, используя также svn:externals.

Сначала убедитесь, что ваш общий код находится в репозитории, независимо от каких-либо спецификаций. c проект. Далее, в вашем заданном c проекте вам нужно будет использовать svn propset

svn propset svn:externals 'http://example.com/svn/common-code/trunk common' .

Теперь у вас есть каталог с именем common в root вашего дерева, который содержит ревизию HEAD общий код. Вы также можете привязать указанную ревизию c (которую я рекомендую, чтобы вы могли проверить старые ревизии без их поломки). Мне нравится использовать скрипт, который периодически проверяет, был ли обновлен мой внешний репозиторий, а затем изменяет версию с привязкой.

Для получения дополнительной информации см. svn book или svn help propset

Mirror

Возможно, вы хотите, чтобы репо B было зеркалом репо А. Если вы это сделаете, то репо В должно быть доступно только для чтения обычным пользователям и доступно для записи только для процесса svnsync.

У меня меньше опыта с svnsync, но он существует и задокументирован здесь:

http://svnbook.red-bean.com/en/1.7/svn.ref.svnsync.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...