如何修复 SVN 导入时的行尾错误?

12

我需要导入一个巨大的 SVN 代码仓库,需要将其从一个服务器转移到另一个服务器。因此,我从旧服务器导出了它:

svnadmin dump . > archive.svn

并在新的上导入:

svnadmin load . < archive.svn
在导入过程中,我遇到了这个错误:
Cannot accept non-LF line endings in 'svn:ignore' property

我该如何解决这个问题?我对两台服务器都有完全的控制。

9个回答

14

你有两个选择,修复源代码或禁用属性验证。

修复源代码(svn:log和svn:ignore):

sed -e '/^svn:log$/,/^K / s/^M/ /' -e '/^svn:ignore$/,/^PROPS-END$/ s/^M/\n/' archive.svn > repaired-archive.svn

svnadmin load . < repaired-archive.svn

其中^M是一个控制字符,表示16进制中的0D。要获取它,请使用^V^M(控制V控制M),而不是 ^M(插入符号M或控制M)。

禁用属性验证:

svnadmin load --bypass-prop-validation . < archive.svn

请注意,上面的sed命令在加载二进制文件时会给我返回错误“svnadmin:E200014:校验和不匹配”。@tangens的sed对我有效。 - ceilfors
我刚刚成功修复了一个转储文件,请查看下面的答案。 - Tobias Knauss

7
@ventura10提供的第一个选项听起来不错,但对我没有用。sed命令改变了属性部分之外的一些版本内容,导致加载转储时md5不匹配。
因为我的存储库没有包含二进制内容的属性,所以我更改了sed命令,以便纠正所有属性,而不仅仅是svn:logsvn:ignore。我也确定没有版本化的文件包含以Prop-content-length:开头的行。否则,在加载转储时我会遇到错误。
sed -e '/^Prop-content-length: /,/^PROPS-END$/ s/^M/ /' svn.dump > svn.dump.repaired

重要的是将^M替换为[空格],因为属性值的大小不应改变。
@ventura10的注释仍然有效:
^M是控制字符,表示十六进制的0D。使用^V^M(控制V控制M)而不是^M(插入符号M或控制M)来获取它。
很难相信将现有存储库从svn 1.4升级到svn 1.7会使这一步骤成为必要的,但我没有找到其他摆脱回车符的方法,因为自svn 1.6以来已不再接受回车符。

您可以在命令 sed -e '/^Prop-content-length: /,/^PROPS-END$/ s/\x0D/ /' svn.dump > svn.dump.repaired 中使用十六进制值。 - ceilfors

7

通过使用svnsync,您可以轻松解决此问题,并具有修复EOL的能力。假设您的存储库已转储到archive.svn中。

首先创建要加载存储库的存储库,忽略EOL问题:

svnadmin create repo
svnadmin load repo < archive.svn --bypass-prop-validation

现在创建一个新的代码库以进行复制:
svnadmin create repo-fixed

svnsync需要一些预提交钩子,即使您不使用它,因此只需使用编辑器在repo-fixed/hooks/pre-revprop-change中创建一个空的预提交钩子:

#!/bin/sh
exit 0

svnsync 初始化目标仓库:

svnsync init file:///path/to/repo-fixed file:///path/to/repo

现在将整个存储库复制过来:
svnsync sync file:///path/to/repo-fixed

哇!svnsync甚至会给你好消息:注意:将svn:*属性标准化为LF换行符结束符(为什么Subversion团队没有更新svnadmin执行相同的标准化,这对我来说是个谜。)

完成后,转储新存储库:

svnadmin dump repo-fixed > archive-fixed.svn

现在您有了archive-fixed.svn,它应该与archive.svn完全相同,只是必要时已经修复了EOLs。

(可选) 您现在可以删除用于svnsync的临时仓库:

rm -rf repo-fixed
更新:如果您加载此新转储,则Subversion客户端会出现错误:Repository UUID does not match expected UUID。您需要使用svnadmin setuuid ...将UUID ID更改为以前的ID。(更改UUID ID为以前的ID)
(本文是我在网上找到的多个片段和部分解决方案的总结。感谢所有比我更了解的人;我只是把它们组合在一起。)
另请参见:

3
做得好!我发现我需要给这个钩子设置执行权限:chmod u+x gjbh-fixed/hooks/pre-revprop-change。 - boes

4
您是否更改了服务器版本?这是1.6中已知的问题,当从1.4或1.5转移时会导致问题。
Subversion 1.6不再接受属性文件中的回车符(^M)。您需要修复svn:ignore文件中的换行符,或者如果更容易,则重新创建该文件。
或者,您可以选择Subversion 1.7,或使用uberSVN

1
我将旧服务器更新到最新版本,但仍然遇到相同的问题。 - xsl
你之前用的是什么?你尝试过设置文件属性以确保使用正确的格式吗?这里有一篇很好的文章(https://mikewest.org/2006/06/working-with-subversion-file-properties)解释了如何做... - Mand Beckett
最终我通过传递参数给svnadmin load命令来忽略行结束符。 - xsl
1
请发布您用于忽略行结尾的参数。 - Troy

3

使用svndumptool

svndumptool.py eolfix-prop svn:ignore svn.dump svn.dump.repaired

@tangens的解决方案对我也有效,但它并不完美,因为我得到了一个额外的空格字符来替换回车符。然而,我已经测试过svn:ignore仍然可以使用这个额外的空格,但我没有测试其他的SVN属性。

使用svndumptool的缺点是它只能一次处理一个svn属性,如果你的转储文件很大,那么会很耗时。


一些发现

你可能会好奇为什么@tangens没有用空字符替换^M。如果你尝试用空字符替换它,你会得到这个错误:

svnadmin: E140001: Dumpstream data appears to be malformed

转储文件存储Prop-content-length属性,该属性将与实际内容匹配。 将^M替换为空字符将减少属性内容长度,因此会出现错误。
svndumptool将分别更改Prop-content-lengthContent-length

我刚刚下载并安装了svndumptool.py 0.6.1,但是找不到“eolfix-prop”命令! - Garret Wilson
看起来该命令只在版本0.6.1之后添加。正如您在此提交中所看到的,它的日期是2013年。即使是版本0.7.0提交,也是在2009年完成的。 - ceilfors
那么我该如何获取这些较新的版本呢?我能找到的最新版本是0.6.1。 - Garret Wilson
@GarretWilson:从 Github 主分支下载即可。 - Christopher Oezbek

2
我在将1.6仓库升级到1.8时遇到了这个错误。我在网上找到了许多“修复”方法。 --bypass-prop-validation 对我来说不是很吸引人,因为它只是推迟了问题,下次你需要恢复仓库时还会遇到同样的问题。
我找到了一个bash脚本来循环遍历修订版本并重新设置注释,但这没有起作用。
ventura10的解决方案有所改进,最终解决了问题。由于转储的大小,我最终使用了单个命令来删除恢复转储时不需要的字符。
    sed -e '/^svn:log$/,/^K / s/^M/ /' -e '/^svn:ignore$/,/^PROPS-END$/ s/^M/\n/' /path/to/svn.dump | svnadmin load /path/to/repo

注意:

^M是一个控制字符,它在十六进制中表示0D。要获取它,请使用^V^M(控制V控制M)代替^M(插入符M或控制M)。


1

我使用了svnadmin load --normalize-props {myrepo} < {mydumpfile},它完美地工作了。

选项--normalize-props是在subversion 1.10中添加的。有关详细信息,请参阅https://subversion.apache.org/docs/release-notes/1.10.html#normalize-props

为方便起见再次复制 -

新的--normalize-props选项用于svnadmin load

svnadmin load命令已添加了一个新的--normalize-props选项。可以使用此选项自动修复属性(例如svn:log或svn:ignore)中的非LF行结尾。旧服务器接受此类无效行结尾,并且可以在旧存储库的存储库转储中找到它们,但是Subversion 1.6及更高版本会拒绝它们。

使用--normalize-props调用svnadmin load将自动修复在转储流中发现的所有无效属性行结尾,从而确保适当的值加载到存储库中。


2
它不起作用,我正在使用 SVN 版本 1.13,但不知何故仍然失败。 - Faizan Akram Dar
1
只是为了记录:使用1.10.4对我也没有帮助。 - zb226

1
我刚刚成功地修复了一个svn转储文件。它还在属性中有一个CRLF,这导致在SVN Edge 转储导入时出现异常(他们有一个非常糟糕的导入例程)。然后我为测试“安装”svnserve,这比预期的要容易得多(适用于Windows操作系统的说明):
  1. 下载并安装TortoiseSVN或另一个包含svn命令行工具的软件。我已经安装了它
  2. 启动cmd.exe,运行svnserve -d。此cmd窗口现在正在忙碌。
  3. 启动另一个cmd.exe创建一个repo:svnadmin create d:\svn_repos\test12
  4. 将转储加载到repo中:svnadmin load d:\svn_repos\test12 < d:\temp\svn\backup_test.dump

svnserve会给你详细的失败信息。

这是需要修复的内容(左侧为原始内容,右侧为修复后的内容): enter image description here


0

我的问题是提交的注释太长了。


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