如何在整个代码库中迁移svn:externals属性中的所有URL?

15

我们正在将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,以便我们仍然可以检出这些项目的早期修订版本而没有破损的链接。

我应该怎样做?


3
你指的“svn://localhost/”这个东西,是指哪一节课? - conny
我的意思是,尽可能使用通用主机名而不是特定的域名,因为当域名更改时,我最终会遇到像这样的混乱。 = / - Nik Reiman
5
我认为没有必要使用 svn://localhost 前缀。你知道可以使用相对路径吗?请参阅 http://subversion.tigris.org/svn_1.5_releasenotes.html#externals - Andrea Francia
6个回答

19

我会使用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 格式 的链接,并使用相对URL。

因此,svn:externals 将变为:

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

成为:

 /repo/libraryA external/libraryA

使用服务器根路径相对URL。


我不理解正则表达式后面的第二部分。能否请您详细说明一下?谢谢。 - moujib
1
我添加了相关链接并对答案进行了更多的澄清。希望这可以帮助到您。 - ldav1s
请参阅此帖子:https://dev59.com/ynvaa4cB1Zd3GeqPFp9N?lq=1 - Ausmith1
对于所有的 Linux 新手:使用 tar --no-same-owner -xvzf svndumptool-0.6.1.tar.gz 解压 svndumptool,进入新目录,使用 ./setup.py install 进行安装,然后不要忘记在命令行中添加 .py - JCH2k

8

由于您想查看旧版本的记录,唯一的解决方案是重新编写整个历史记录(前面提到的D解决方案)。

为此,您需要:

1)使用svnadmin dump命令转储整个仓库的内容:

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

2) 编辑转储文件,更改svn:externals网址。 这是最困难的部分:假设仓库还包含二进制数据,在纯文本编辑器中打开转储文件很可能会损坏该文件。我使用过一种称为“十六进制编辑器”的工具,并取得了良好的效果,例如免费的十六进制编辑器XVI32

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

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

更多信息,请参考以下链接:
http://svnbook.red-bean.com/en/1.1/ch05s03.html

注意:Subversion 1.5实际上在svn:externals属性中添加了对相对URL的支持,这可以精确地防止未来出现此类问题:
http://subversion.tigris.org/svn_1.5_releasenotes.html#externals


这是解决方案,但您真的不想在编辑器中打开一个 -即使是中等大小的- svn 转储文件... 'sed' 来拯救! - jeroenh
1
除非你愿意处理文件和属性数据的MD5和SHA1哈希,否则不应该使用文本编辑器编辑SVN转储。手动重新计算这些哈希使得对超过几十个版本的SVN转储文件进行手动编辑成为一项艰巨的工作。最好使用专门用于此任务的工具之一,例如svndumptool。 - Ausmith1

1
我使用vi编辑了我的转储文件,但是我必须使用"-b"开关以二进制模式进行编辑,这样任何可能被解释为行结尾的字符都不会被转换。
例如:vi -b filename.dump 此外,我发现如果URL长度发生变化,某些字符串长度也必须修改。例如,考虑以下条目:
Node-path: trunk/src/include Node-kind: dir Node-action: change Prop-content-length: 192
Content-length: 192
K13
svn:externals
V 156
MGL_ABC svn://server_name/dir1/dir2
MGL_DEF svn://server_name/dir1/dir3
当您修改这些URL时,如果字符串的长度发生变化,则需要将“192”、“192”和“156”更改为与新长度匹配。我发现计算绝对长度很困难,但很容易找到差异。
例如,假设URL 1缩短了3个字符,URL 2缩短了4个字符。然后,您需要从这三个字符串长度数字中减去“7”。

1
我需要将 12 个工作副本从 9 个用户和 4 个部署中重新定位。这是一个简单的更改,用 IP 替换域名,即 thing.domain.net -> 192.168.0.1
期望svn relocate按照描述的方式运行(遍历嵌套的 externals),我编写了一个简单的 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 查找中): 设置->保存的数据->URL 历史记录->清除

0

我所有的外部文件都在名为flow的目录中。我使用这个一行命令(bash shell)修复了我的外部文件中的URL:

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

0

你可以:

a)查看旧版本,并将您的hosts文件更改为将旧名称指向新地址,然后进行svn更新。如果URL路径也发生了变化...那么您可能也可以:

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

c)记录您检入新属性值的修订版本,检出旧版本,然后将这些修订版本(仅影响属性)合并到您的工作副本中。

d)或者,可能使用svndump转储存储库数据,替换转储中的URL,然后恢复它...我不能保证它甚至能正常工作;-)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接