如何跨存储库迁移svn:externals属性中的所有URL?

如何跨存储库迁移svn:externals属性中的所有URL?,svn,migration,repository,externals,Svn,Migration,Repository,Externals,我们正在将我们的SVN存储库从一台机器移动到另一台机器,随之而来的将是新repo的新域名。问题是,在存储库中,有很多svn:externals引用到存储库中的其他项目。例如,我们有projectA,它在svn:externals属性中有: external/libraryA svn://oldserver.net/repo/libraryA external/libraryB svn://oldserver.net/repo/libraryB ……等等。所有的URL都引用了这个特定的域名,因此

我们正在将我们的SVN存储库从一台机器移动到另一台机器,随之而来的将是新repo的新域名。问题是,在存储库中,有很多svn:externals引用到存储库中的其他项目。例如,我们有projectA,它在svn:externals属性中有:

external/libraryA svn://oldserver.net/repo/libraryA
external/libraryB svn://oldserver.net/repo/libraryB
……等等。所有的URL都引用了这个特定的域名,因此它可以很容易地被解析。已经吸取了教训,我将把这些URL迁移到“svn://localhost/“,但我需要找到一种方法来浏览存储库历史并重写所有旧的URL,这样我们仍然可以在没有断开链接的情况下检查这些项目的旧版本

我该怎么做呢?

你可以:

a) 签出旧版本,更改主机文件,将旧名称指向新地址,然后进行svn更新。如果URL路径也发生更改。。。那么你不妨:

b) 花点时间编写一个脚本,在当前(旧版本)工作副本中查找属性并在那里更改URL,而不提交它们。或:

c) 记下签入新特性值的修订(-s),签出旧版本,然后将这些修订(-s)合并到工作副本中


d) 或者,可能使用svndump转储存储库数据,字符串替换转储中的URL,然后还原它。。我不会给你任何保证,即使是工作;-)

正如您所指出的,您仍然希望能够签出旧版本,唯一的解决方案是真正“重写”整个历史记录(前面提到的解决方案D)

为此,您应该:

1) 使用以下命令转储整个存储库的内容:

2) 编辑转储文件,以更改svn:externals URL这是最困难的部分:假设存储库也包含二进制数据,在纯文本编辑器中打开转储文件很可能会损坏转储文件。我在使用所谓的“十六进制编辑器”(hex editor)方面有很好的经验,例如

3) 创建新存储库并将修改后的转储文件加载到其中:

$ svnadmin create newrepos
$ svnadmin load newrepos < modified-dumpfile
$svnadmin创建新回购
$svnadmin load newrepos
有关更多信息,您可能还对以下链接感兴趣:

注意:Subversion 1.5实际上在svn:externals属性中添加了对相对URL的支持,这可以准确地防止将来出现此类问题:

我会用这个。它正是您想要的:

svndumptool transform-prop svn:externals "(\S*) (|-r ?\d* ?)http://oldserver.net(/\S*)" "\2\3 \1" source.dumpfile source-fixed-externals.dumpfile
这将修复每个外部URL,并使用相对URL

所以svn:外部像:

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

 /repo/libraryA external/libraryA

使用服务器根相对URL。

我必须跨9个用户和4个部署重新定位12个工作副本。这是一个简单的改变,用IP替换域,即
thing.domain.net->192.168.0.1

我希望svn relocate
能够按照所描述的方式运行(遍历嵌套的外部对象),因此我编写了一条简单的DOS指令,在每个位置运行:

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

这没有按预期工作,只是重新定位了父WC

我的解决方案是编辑存储库本身(我使用了Tortoise Repo浏览器)来更改外部的位置。在此更改之后,只需更新重新定位的父对象,即可使所有内容保持一致

让所有乌龟用户清除其URL历史记录可能是一个好主意,这样他们就不会无意中使用旧URL执行操作(它仍然存在于DNS查找中):


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

我用vi编辑了我的转储文件,但我不得不使用“-b”开关以二进制模式编辑,这样就不会转换任何可能被解释为行尾的字符

e、 g.vi-b filename.dump

此外,我发现,如果URL长度发生变化,也必须修改字符串长度。 例如,考虑一个这样的条目:

节点路径:trunk/src/include

节点类型:dir

节点操作:更改

道具内容长度:192

内容长度:192

K13

svn:外部

第156节

MGL_ABCsvn://server_name/dir1/dir2

MGL_DEFsvn://server_name/dir1/dir3

当您修改这些URL时,如果字符串的长度改变,您还需要更改“192”、“192”和“156”以匹配新的长度。 我发现很难计算绝对长度,但很容易找到微分。

例如,假设URL 1变短3个字符,URL 2变短4个字符。然后,您必须从这三个字符串长度的数字中分别提取“7”。

我所有的外部数据都在名为
flow
的目录中。我用一行代码(bashshell)修复了外部URL:

对于p,单位为$(find-maxdepth 4-name-flow);做svn-ps-svn:externals“$(svn-pg-svn:externals$p/。| perl-pe's/^(\w+)svn\+ssh.*thing\.domain\.net(.*)/$2$1/”)“$p/。。;完成
“你指的是什么特别的教训?”svn://localhost/“-事情?我的意思是,如果可能的话,应该使用通用主机名而不是特定的域名,因为当域名发生变化时,我最终会陷入这样的混乱=/我认为没有必要使用svn://localhost 前缀你知道你可以使用相对URL吗?看,这就是解决方案,但你真的不想在编辑器中打开一个甚至中等大小的svn转储文件去营救!除非您愿意处理文件和道具数据的MD5和SHA1散列,否则不应该使用文本编辑器编辑SVN转储。手动重新计算这些散列使得手工编辑SVN转储文件成为可能
 /repo/libraryA external/libraryA
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