修复损坏的SVN代码库

10
我在 Mac OS X Lion (10.7.2 11C74) 上使用 svnX (0.9.13),似乎遇到了一个我认为是破损的 SVN 仓库。我已经在网站上搜索了类似的问题,并找到了一 解决方案,但没有一种描述当您无法完成从仓库的checkout时如何恢复的方法。我也没有最新的工作目录。
具体错误如下:

svn: Checksum mismatch while reading representation:
expected: [hash]
actual: [different hash]

如果关闭警报(唯一的选项),则 checkout 将继续执行直到结束。乍一看,大多数文件似乎都在那里,但是当我运行应用程序时,显然版本混乱。仓库位于 USB 闪存驱动器上,这可能是损坏的来源。我是访问这些文件的唯一用户,它们已经有一个星期没有被碰过并且处于工作状态。
欢迎提供关于如何进行操作的建议。

@derobert 可以从备份中恢复,但会丢失一些提交记录,因此我只会在万不得已的情况下尝试这样做。 - Noren
你唯一的希望就是执行 svnadmin dump and load 命令,看看是否能解决损坏问题。 - David W.
@derobert 是的,我在发布之前尝试了两个 可能的解决方案。我认为现在最好的解决方案是创建一个包含当前修订版本但失去历史记录的新存储库。 - Noren
1
@Noren - 在 svnadmin 的 dump 命令中,你可以通过 -r 参数指定一个版本范围。尝试跳过错误的版本,看看是否有帮助。如果你有备份,你可能可以从备份中进行一次 dump,然后开始对当前版本进行 dump,直到备份之后的版本。然后,将两个 dump 文件合并起来,看看会发生什么。除此之外,你没有太多选择。这就像硬盘崩溃时会发生的情况。你尽力挽救能挽救的,希望一切都能好起来。 - David W.
@DavidW。使用多个svnadmin dump范围,我能够保留一些历史记录和最新的修订版本。请发布一个答案帖子,这样我就可以关闭该线程。谢谢! - Noren
显示剩余5条评论
2个回答

18

当你的仓库出现损坏时,唯一拯救信息的希望就是进行转储和加载。如果你很幸运,进行转储和加载有时会纠正损坏。

如果不行,你可以在导出文件中使用 -r <from>:<to> 参数来跳过错误的版本。你可以创建多个导出文件并将它们合并成一个仓库,这样你就可以跳过坏版本号了。我注意到每个导出文件都以该版本的完整仓库修订开始,而且转储/加载过程通常足够聪明,不会使更改重复。

事实上,我相信即使将多个导出文件放入单个导出文件中也没有太大问题。以下命令应该跳过版本1001和1204,这两个版本都有问题:

$ svnadmin dump -r1:1000 my_repos > dumpfile.txt
$ svnadmin dump --incremental -r1002:1203 my_repos >> dumpfile.txt
$ svnadmin dump --incremental -r1205:HEAD my_repos >> dumpfile.txt
$ svnadmin load my_repos2 < dumpfile.txt

有几个 Subversion 备份脚本通过获取最新修订版本的转储来备份存储库。例如,第一次运行脚本时,它会将从第一个修订版本到最后一个版本(比如第1000个修订版本)的所有内容都进行转储。然后,第二天将转储从修订版本1001开始到最后一个版本(比如1003),第三天从修订版本1004开始转储到最后一个版本。

要进行恢复,您必须还原所有的转储,但备份时间应该比每次完全转储短。

您也可以使用 hotcopy 进行备份,但我发现做 hotcopy 比做转储并没有快多少,并且如果你必须将存储库移动到另一台机器上可能会出现问题。


1
上述方法对我有效,但有一个例外:我必须使用“--incremental”开关来确保svnadmin的路径正确。 - eazy
先生,您刚刚救了我一个大忙 :-)。因为HEAD似乎无法识别,或者导致转储产生了奇怪的错误,所以我只能一个一个地转储修订记录。 - Nux
1
有时属性会损坏,这时在 svnadmin load 命令中使用 --bypass-prop-validation 选项。 - Znik
1
如果我在加载过程中遇到错误:“*编辑路径...svnadmin:E160013:文件未找到:事务'2-2',路径...”?我的问题出在一些早期的修订版本上(第3和5个,现在我在第65个)。 - unlikely

6

正如David W.所建议的,您应该进行转储和加载。但是,我遇到了一些问题,并且想要发布完整的解决方案。

通常在某些修订版本的单个文件中会发生损坏。我们不需要仅因为某个文件的校验和不匹配就放弃整个修订版本。

首先,我们将尝试禁用校验和计算,通过删除与Text-content-md5匹配的行。

svnadmin dump my_repo | sed '/^Text-content-md5/d' | svnadmin load second_repo

增量方法使我们能够修复错误并继续前进。如果在转储和加载过程中发生错误,请查找最后一个--- Committed revision X >>> ---消息,并将X+1作为-r参数的起始版本,然后再次尝试。这可以节省大量时间。

svnadmin dump --incremental -r1:100000 my_repo | sed '/^Text-content-md5/d' | svnadmin load second_repo

或者只需从dumpfile加载:

sed '/^Text-content-md5/d' dumpfile.txt | svnadmin load second_repo

如果不够了解,你可能会遇到'Premature end of content data in dumpstream'或类似错误,这时应该通过svndumpfilter完全排除该文件:
svnadmin dump --incremental -r1:100000 my_repo | svndumpfilter exclude myproject/lib/thirdparty-all.jar | sed '/^Text-content-md5/d' | svnadmin load second_repo

上述命令从转储中排除了myproject/lib/thirdparty-all.jar文件。
额外信息:
- 如果损坏不严重,可以将--bypass-prop-validation添加到svnadmin load命令。 - 通过在管道链中(在svnadmin load之前)添加
| grep --binary-files=text -v '^* Dumped revision'
来修复Dump stream contains a malformed header (with no ':')错误。
希望这篇文章对一些人有用。

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