我必须导入一个巨大的 SVN 存储库,我必须将其从一台服务器传输到另一台服务器。所以我从旧服务器导出了它:
svnadmin dump . > archive.svn
并将其导入新的:
svnadmin load . < archive.svn
在导入过程中,我收到此错误:
Cannot accept non-LF line endings in 'svn:ignore' property
我怎样才能解决这个问题?我完全控制了两台服务器。
我必须导入一个巨大的 SVN 存储库,我必须将其从一台服务器传输到另一台服务器。所以我从旧服务器导出了它:
svnadmin dump . > archive.svn
并将其导入新的:
svnadmin load . < archive.svn
在导入过程中,我收到此错误:
Cannot accept non-LF line endings in 'svn:ignore' property
我怎样才能解决这个问题?我完全控制了两台服务器。
您有 2 个选项,修复源或禁用道具验证。
修复源(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是控制字符,表示十六进制的 0D。要获得它,请使用 ^V^M ( control V control M ) 而不是 ^M ( circumflex M 或 control M )
禁用道具验证:
svnadmin load --bypass-prop-validation . < archive.svn
@ventura10 答案的第一个选项听起来不错,但对我不起作用。该sed
命令更改了属性部分之外的一些版本化内容,导致加载转储时 md5 不匹配。
因为我的存储库没有包含二进制内容的属性,所以我更改了 sed 命令以更正所有属性,而不仅仅是svn:log
和svn:ignore
. 我还确定没有版本化文件包含以Prop-content-length:
. 否则我在加载转储时会出错。
sed -e '/^Prop-content-length: /,/^PROPS-END$/ s/^M/ /' svn.dump > svn.dump.repaired
^M
替换为 很重要[blank]
,因为属性值的大小不得更改。
@ventura10 的注释仍然有效:
^M 是一个控制字符,即十六进制的 0D。要获得它,请使用 ^V^M(控制 V 控制 M)而不是 ^M(抑扬符 M 或控制 M)
很难相信将现有存储库从 svn 1.4 升级到 svn 1.7 会使这一步变得必要,但我发现没有其他方法可以摆脱自 svn 1.6 以来不再接受的回车。
通过一些体操,您可以使用svnsync
具有修复 EOL 的能力来解决此问题。假设您的存储库被转储在archive.svn
.
首先创建存储库以加载 repo,忽略 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
甚至会给你一个好消息:(NOTE: Normalized svn:* properties to LF line endings
为什么 Subversion 团队没有更新svnadmin
来做同样的规范化对我来说是个谜。)
完成后,转储新的存储库:
svnadmin dump repo-fixed > archive-fixed.svn
您现在拥有,除了 EOL 已根据需要进行修复之外archive-fixed.svn
,它应该与 相同。archive.svn
(可选)您现在可以删除您用于的临时存储库svnsync
:
rm -rf repo-fixed
更新事实证明,如果您加载这个新转储,您的 Subversion 客户端会收到错误:Repository UUID does not match expected UUID
. 您必须使用svnadmin setuuid ...
将UUID ID 更改为以前的.
(这篇文章是我在网上找到的大量片段和部分解决方案的结晶。感谢所有比我了解更多的人;我只是把它们放在一起。)
也可以看看:
你改过服务器版本吗?这是 1.6 中的一个已知问题,从 1.4 或 1.5 开始会导致问题。
Subversion 1.6 不再接受属性文件中的回车符 (^M)。您需要修复 svn:ignore 文件中的换行符,或者如果这样更容易重新创建。
或者,您可以选择Subversion 1.7,或使用uberSVN。
使用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-length
和Content-length
。
我在将 1.6 存储库升级到 1.8 时遇到了这个错误。我在网上找到了许多“修复”。
--bypass -prop-validation对我没有吸引力,因为它推迟了问题,下次你需要恢复 repo 时,你会遇到同样的问题。
我找到了一个 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)
我刚刚成功修复了一个svn转储文件。它的属性中还有一个 CRLF,这导致了 SVN Edge 转储导入中的异常(它们的导入例程非常糟糕)。然后我“安装”了svnserve进行测试,这比预期的要容易得多(Windows 操作系统的说明):
cmd.exe
,运行svnserve -d
。这个 cmd 窗口现在很忙。cmd.exe
创建回购:svnadmin create d:\svn_repos\test12
svnadmin load d:\svn_repos\test12 < d:\temp\svn\backup_test.dump
svnserve 将为您提供失败的详细信息。
我用过svnadmin load --normalize-props {myrepo} < {mydumpfile}
,效果很好。
该--normalize-props
开关被添加到颠覆 1.10。有关详细信息,请参阅https://subversion.apache.org/docs/release-notes/1.10.html#normalize-props
为方便而复制 -
svnadmin 加载的新 --normalize-props 选项
新的 --normalize-props 选项已添加到 svnadmin load 命令。此选项可用于自动修复 svn:log 或 svn:ignore 等属性中的非 LF 行结尾。这种无效的行结尾被旧服务器接受,并且可以在旧存储库的存储库转储中找到,但被 Subversion 1.6 及更高版本拒绝。
使用 --normalize-props 调用 svnadmin load 将自动修复在转储流中找到的所有无效属性行结尾,从而确保将适当的值加载到存储库中。
我的问题是提交的评论太大了。