修复损坏的 SVN 存储库

Posted

技术标签:

【中文标题】修复损坏的 SVN 存储库【英文标题】:Repair corrupted SVN repository 【发布时间】:2012-01-12 20:26:37 【问题描述】:

我在 Mac OS X Lion (10.7.2 11C74) 上使用 svnX (0.9.13) 并且我认为似乎有一个损坏的 SVN 存储库。我已经在网站上搜索过类似的问题,并且有 found 和 couple,但没有人描述当您无法从存储库完成 checkout 时如何恢复。我也没有最新的工作目录。

具体错误是:

svn:读取表示时校验和不匹配: 预期:[哈希] 实际:[不同的哈希]

如果警报被解除(唯一选项),结帐将继续到结束。乍一看,大多数文件似乎都在那里,但是当我运行应用程序时,很明显有一个混杂的版本。存储库位于 USB 闪存驱动器上,这可能是损坏的来源。我是唯一一个访问这些文件的用户,他们已经一个多星期没有被碰过并且处于工作状态。

任何关于如何进行的建议将不胜感激。

【问题讨论】:

从备份中恢复? SVN 以有效的二进制差异格式存储修订,我怀疑这会使其非常容易受到损坏...无论如何,您应该做的第一件事是制作存储库的完整副本,并努力恢复 复制. USB 闪存盘?我希望您定期备份它(如果没有损坏,它甚至可能会丢失)。 @derobert 从备份恢复是可能的,但是一些提交会丢失,所以我只是作为最后的手段尝试这样做。 @crashmstr 是的,驱动器每周都会与开发计算机一起备份,但是,由于无法连接到备份硬件,我在假期休息时工作了一点。我想这是我的忏悔。 @Noren - 在 svnadmin dump 中,您可以通过 -r 参数指定修订范围。尝试跳过糟糕的修订,看看是否有帮助。如果您有备份,则可以从备份中进行转储,然后在备份后开始将当前版本转储到修订版。然后,将两者结合起来,看看会发生什么。你能做的不多。这就像您的硬盘驱动器崩溃时会发生什么。您会尽力保存并希望获得最好的结果。 【参考方案1】:

当您的存储库损坏时,保存信息的唯一真正机会是进行转储和加载。如果幸运的话,执行转储和加载有时会纠正损坏。

如果没有,您可以使用转储上的-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 转储到最后一个修订版。

要还原,您必须还原所有转储,但假设备份时间比每次执行完整转储要短。

您也可以进行热复制,但我发现进行热复制并没有比进行转储快得多,而且如果您必须将存储库移动到另一台机器上,可能会出现问题。

【讨论】:

上述方法对我有用,但有一个例外:我必须使用 svnadmin 的“--incremental”开关来确保路径正确。 你先生,刚刚救了我:-)。我只需要一一转储修订,因为 HEAD 似乎无法识别,或者至少转储产生了奇怪的错误。 有时属性已损坏,然后在 svnadmin load 命令中使用 --bypas-prop-validation 选项。 如果我在加载过程中遇到错误:“* 编辑路径 ... svnadmin: E160013: 找不到文件:事务 '2-2',路径 ...”?我的问题是一些较早的版本(3 和 5,现在我 65 岁)...【参考方案2】:

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

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

首先我们将尝试禁用校验和计算,方法是删除匹配Text-content-md5的行

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

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

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

或者只是从转储文件中加载:

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

如果这还不够,并且您收到“转储流中的内容数据过早结束”错误或类似情况,您应该通过 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 命令。如果损坏很小,则此方法有效。 修复Dump stream contains a malformed header (with no ':') 附加错误| grep --binary-files=text -v '^* Dumped revision' 到管道链(svnadmin load 之前)。

希望这篇文章对某些人有用。

【讨论】:

以上是关于修复损坏的 SVN 存储库的主要内容,如果未能解决你的问题,请参考以下文章

SVN 存储库不断损坏

如何修复我的 TortoiseSVN 存储库中的损坏?

批量验证 svn 存储库

master库损坏如何恢复

如何修复“损坏的”交互式变基?

重新创建SVN wc.db.