Репозиторий svn, который я зеркалирую через git-svn, изменил URL.
В vanilla svn вы бы просто сделали svn switch --relocate old_url_base new_url_base
.
Как я могу это сделать с помощью git-svn?
Простое изменение URL-адреса svn в файле конфигурации не выполняется.
Ответы:
Это хорошо справляется с моей ситуацией:
https://git.wiki.kernel.org/index.php/GitSvnSwitch
Я клонировал с помощью
file://
протокола и хотел перейти на этотhttp://
протокол.Заманчиво изменить
url
настройку в[svn-remote "svn"]
разделе.git/config
, но само по себе это не работает. Как правило, вам необходимо выполнить следующую процедуру:url
настройку svn-remote на новое имя.git svn fetch
. Для этого необходимо получить хотя бы одну новую ревизию из svn!url
настройку svn-remote на исходный URL-адрес.git svn rebase -l
локальную перебазировку (с изменениями, внесенными при последней операции выборки).url
настройку svn-remote на новый URL-адрес.git svn rebase
должно снова работать.Любители приключений могут захотеть попробовать
--rewrite-root
.источник
Вы можете увидеть, работает ли следующее:
Если
svn-remote.svn.rewriteRoot
не существует в файле конфигурации (.git/config
):Если
svn-remote.svn.rewriteUUID
не существует в файле конфигурации:Его
currentRepositoryUUID
можно получить из.git/svn/.metadata
.git config svn-remote.svn.url <newRepositoryURL>
источник
file://
, переключиться наsvn+ssh
); просто обратите внимание на то, что этой процедуре не нужно "получать хотя бы одну новую ревизию из svn"; также./.git/svn/.metadata
после firstsvn rebase
содержит<newRepository>
asreposRoot
- но этого недостаточно, чтобы удалитьrewrite*
ключи.git/config
; таким образом, эти ключи должны храниться там постоянно, насколько я понимаю.svn+ssh://
и наш svn-сервер только что изменил домен с.se
на,.com
чтобы очистить наше внутреннее именование.К сожалению, большинство ссылок в этих ответах не работают, поэтому я собираюсь продублировать небольшую информацию из git wiki для дальнейшего использования.
Это решение сработало для меня:
Отредактируйте
svn-remote
url
(илиfetch
путь),.git/config
чтобы указать на новый домен / URL / путьЗапустите git
git svn fetch
. Для этого необходимо получить хотя бы одну новую ревизию из svn!Если вы попытаетесь
git svn rebase
сейчас, вы получите такое сообщение об ошибке:Я думаю, это потому, что вас
git svn
смущает тот факт, что ваша последняя фиксация перед выборкой будетgit-svn-id
указывать на старый путь, который не соответствует пути, найденному в.git/config
.В качестве обходного пути измените
svn-remote
url
(илиfetch
путь) обратно на исходный домен / URL / путьТеперь запустите
git svn rebase -l
снова, чтобы выполнить локальную перебазировку с изменениями, внесенными при последней операции выборки. На этот раз он будет работать, по- видимому , потому , чтоgit svn
не следует путать с тем , чтоgit-svn-id
новым главой не совпадает с найденным в.git/config
.Наконец, измените
svn-remote
url
(илиfetch
путь) обратно на новый домен / URL / путьНа этом этапе
git svn rebase
должно снова работать!Первоначальная информация была найдена здесь .
источник
Git svn сильно зависит от URL-адреса svn. Каждый коммит, импортированный из svn, имеет
git-svn-id
URL-адрес svn.Допустимая стратегия перемещения - вызвать
git-svn clone
новый репозиторий и объединить изменения с этим новым закрытием. Более подробную процедуру можно найти в этой статье:http://www.sanityinc.com/articles/relocating-git-svn-repositories
источник
git filter-branch
Этот сценарий , взятый из записи в блоге , работал у меня. Укажите старый и новый URL-адреса репо в качестве параметра, как для
svn switch --relocate
.Сценарий вызывает
git filter-branch
замену URL-адресов Subversion вgit-svn-id
сообщениях фиксации, обновлениях.git/config
, а также обновляетgit-svn
метаданные, воссоздавая их с помощьюgit svn rebase
. Хотяgit svn clone
этотfilter-branch
подход может быть более надежным решением, он работает намного быстрее для огромных репозиториев (часы против дней).#!/bin/sh # Must be called with two command-line args. # Example: git-svn-relocate.sh http://old.server https://new.server if [ $# -ne 2 ] then echo "Please invoke this script with two command-line arguments (old and new SVN URLs)." exit $E_NO_ARGS fi # Prepare URLs for regex search and replace. oldUrl=`echo $1 | awk '{gsub("[\\\.]", "\\\\\\\&");print}'` newUrl=`echo $2 | awk '{gsub("[\\\&]", "\\\\\\\&");print}'` filter="sed \"s|^git-svn-id: $oldUrl|git-svn-id: $newUrl|g\"" git filter-branch --msg-filter "$filter" -- --all sed -i.backup -e "s|$oldUrl|$newUrl|g" .git/config rm -rf .git/svn git svn rebase
источник
git_fast_filter
Тем не менее, быстрее, чем
git-filter-branch
(то есть минуты вместо часов), но похожий по духу, это использоватьgit_fast_filter
. Однако для этого требуется немного больше кода, и не существует аккуратного готового решения. В отличие отgit-filter-branch
, это создаст новое репо из старого . Предполагается, что этоmaster
указывает на последнюю фиксацию SVN.git_fast_filter
из репо Gitorious.git_fast_filter
на основе этого Gist , установите исполняемый бит, используяchmod +x
. Адаптируйте старые и новые пути к репозиторию. (Содержание скрипта тоже вставлено ниже.)git init
, измените рабочий каталог на это новое репозиторий .Выполните следующую трубу:
Скопируйте
.git/config
и, возможно, другие соответствующие файлы.git/info
из старого репо в новое репо..git/svn
.Обратите внимание
git-svn
на новое сопоставление номеров ревизийВыполнить
git branch refs/remotes/git-svn master
refs/remotes/git-svn
, консультации.git/config
,svn-remote
секцииВыполнить
git svn info
. Если эта команда зависает, что-то не так. Он должен перестроить отображение номера ревизии.Удалите поддельную ветку
refs/remotes/git-svn
, она будет воссозданаgit-svn
git svn rebase
.Ниже приведено содержимое
commit_filter.py
, замените значенияIN_REPO
иOUT_REPO
при необходимости:#!/usr/bin/python from git_fast_filter import Commit, FastExportFilter import re import sys IN_REPO = "https://svn.code.sf.net/p/matsim/code" OUT_REPO = "https://svn.code.sf.net/p/matsim/source" IN_REPO_RE = re.compile("^git-svn-id: %s" % re.escape(IN_REPO), re.M) OUT_REPO_RE = "git-svn-id: %s" % OUT_REPO def my_commit_callback(commit): commit.message = IN_REPO_RE.sub(OUT_REPO_RE, commit.message) sys.stderr.write(".") filter = FastExportFilter(commit_callback = my_commit_callback) filter.run()
источник
Вышеупомянутое
git svn rebase -l
решение не сработало для меня. Я решил пойти другим путем:old
а новый SVN - в репозиторий gitnew
old
вnew
cd new
git fetch ../old
git tag old FETCH_HEAD
new
на вершинеold
(должно быть успешным, потому что деревья в корнеnew
и на вершинеold
идентичны)git checkout master
(Предполагается, чтоmaster
ветвь указывает на головку SVN. Так будет с чистым клоном; в противном случае dcommit перед началом.)git rebase --root --onto old
new
для учета перебазированияgit update-ref --no-deref refs/remotes/git-svn master
(отрегулируйте удаленный ref в зависимости от того, как вы клонировали, например, это могло бытьrefs/remotes/svn/trunk
)rm -r .git/svn
git svn info
источник
Основываясь на некоторых других ответах на этот вопрос, я придумал сценарий Ruby, который обрабатывает перемещение git-svn. Вы можете найти его на https://gist.github.com/henderea/6e779b66be3580c9a584 .
Он обрабатывает перемещение, не проверяя другую копию, и даже обрабатывает случай, когда в одной или нескольких ветвях есть не отправленные изменения (поскольку это нарушает обычную логику). Он использует материал из ответа git filter-branch (для основной логики) и ответ о копировании ветвей из одного экземпляра репо в другой (для копирования ветвей с неопталкиваемыми изменениями).
Я использовал это, чтобы переместить кучу репозиториев git-svn, которые у меня есть для работы, и эта версия скрипта (я прошел через бесчисленное количество итераций), похоже, мне подходит. Это не очень быстро, но похоже, что он справляется со всеми случаями, с которыми я сталкивался, и приводит к полностью перемещенному репо.
Сценарий дает вам возможность создать копию репо перед внесением каких-либо изменений, поэтому вы можете использовать эту опцию для создания резервной копии. Создание копии требуется, если у вас есть неопубликованные изменения в каких-либо ветвях.
Скрипт не использует гемов или других библиотек, не включенных в обычную установку MRI Ruby. Он действительно использует библиотеки readline и fileutils, включенные в MRI.
Надеюсь, мой сценарий окажется полезным для кого-то еще. Не стесняйтесь вносить изменения в сценарий.
ПРИМЕЧАНИЕ. Я тестировал этот сценарий только с git 2.3.0 / 2.3.1 и Ruby 2.2.0 на OS X 10.10 Yosemite (поскольку это среда, которую я использую), но я ожидаю, что он будет работать и в других средах. Однако никаких гарантий насчет Windows.
источник