本手册旨在描述 Subversion 1.1。如果您运行的是更新版本的 Subversion,我们强烈建议您访问 https://svnbooks.subversion.org.cn/ 并查阅适合您 Subversion 版本的版本。

附录 B. 故障排除

目录

常见问题
使用 Subversion 时遇到的问题
每次我尝试访问我的存储库时,我的 Subversion 客户端都会挂起。
每次我尝试运行 svn 时,它都会说我的工作副本被锁定。
我在查找或打开存储库时遇到错误,但我知道我的存储库 URL 是正确的。
如何在 file:// URL 中指定 Windows 驱动器号?
我在通过网络对 Subversion 存储库执行写入操作时遇到问题。
在 Windows XP 下,Subversion 服务器有时似乎会发送损坏的数据。
在 Subversion 客户端和 Apache 服务器之间的对话中进行网络跟踪的最佳方法是什么?
我刚刚构建了发行版二进制文件,当我尝试检出 Subversion 时,我收到关于无法识别的 URL 方案的错误。
为什么 svn revert 命令需要显式目标?为什么它不是默认递归的?此行为与几乎所有其他子命令不同。
当我启动 Apache 时,mod_dav_svn 会抱怨数据库版本错误,它找到了 db-3.X,而不是 db-4.X。
我在 RedHat 9 上收到未实现函数的错误,没有任何效果。我该如何解决?
为什么日志会显示(无作者)以供通过 Apache(ra_dav)提交或导入的文件?
我在 Windows 上偶尔会收到访问被拒绝的错误。它们似乎随机发生。
在 FreeBSD 上,某些操作(尤其是 svnadmin create)有时会挂起。
我可以在网页浏览器中看到我的存储库,但 svn checkout 给了我关于 301 Moved Permanently 的错误。
我试图查看文件的旧版本,但 svn 说路径未找到。

常见问题

在安装和使用 Subversion 的过程中,您可能会遇到一些问题。其中一些问题将在您更好地了解 Subversion 的工作方式后得到解决,而另一些问题则是由于您习惯了其他版本控制系统的使用方法造成的。还有其他一些问题可能无法解决,因为 Subversion 运行的一些操作系统的错误(考虑到 Subversion 运行的广泛的 OS,令人惊讶的是我们没有遇到更多这样的问题)。

以下列表是在多年 Subversion 使用过程中编制的。如果您在这里找不到您遇到的问题,请查看 Subversion 主网站上最新版本的常见问题解答。如果您仍然遇到问题,请发送邮件至并详细描述您遇到的问题。[45]

使用 Subversion 时遇到的问题

以下是一些 Subversion 常见问题解答中最常见的问题。

每次我尝试访问我的存储库时,我的 Subversion 客户端都会挂起。

您的存储库没有损坏,您的数据也没有丢失。如果您的进程直接访问存储库(mod_dav_svn、svnlook、svnadmin 或如果您访问file://URL),那么它正在使用 Berkeley DB 来访问您的数据。Berkeley DB 是一个日志系统,这意味着它会在执行操作之前记录所有要执行的操作。如果您的进程被中断(例如,通过 kill 信号或段错误),那么会留下一个锁文件以及描述未完成业务的日志文件。任何尝试访问数据库的另一个进程都会挂起,等待锁文件消失。要唤醒您的存储库,您需要要求 Berkeley DB 完成工作或将数据库倒回到已知一致的先前状态。

确保您以拥有和管理数据库的用户身份运行此命令,而不是以 root 身份运行,否则它会在 db 目录中留下 root 拥有的文件。这些文件无法由管理数据库的非 root 用户打开,该用户通常是您或您的 Apache 进程。还要确保在运行恢复时设置了正确的 umask,因为失败会导致锁定允许访问存储库的组中的用户。

只需运行

$ svnadmin recover /path/to/repos

命令完成后,检查存储库的db/目录中的权限。

每次我尝试运行 svn 时,它都会说我的工作副本被锁定。

Subversion 的工作副本与 Berkeley DB 一样,使用日志机制来执行所有操作。也就是说,它会在执行操作之前记录所有要执行的操作。如果 svn 在执行操作时被中断,那么会留下一个或多个锁文件,以及描述未完成操作的日志文件。(svn status 会显示L在锁定的目录旁边。)

任何尝试访问工作副本的另一个进程在看到锁时都会失败。要唤醒您的工作副本,您需要告诉客户端完成工作。要解决此问题,请从您的工作副本的顶部运行此命令

$ svn cleanup

我在查找或打开存储库时遇到错误,但我知道我的存储库 URL 是正确的。

参见 名为“每次我尝试访问我的存储库时,我的 Subversion 客户端都会挂起。”的部分

您还可能在打开存储库时遇到权限问题。参见 名为“支持多种存储库访问方法”的部分

如何在file://URL 中指定 Windows 驱动器号?

参见 存储库 URL

我在通过网络对 Subversion 存储库执行写入操作时遇到问题。

如果导入在本地访问时工作正常

$ mkdir test
$ touch test/testfile
$ svn import test file:///var/svn/test -m "Initial import"
Adding         test/testfile
Transmitting file data .
Committed revision 1.

但不在远程主机上

$ svn import test http://svn.red-bean.com/test -m "Initial import"
harry's password: xxxxxxx

svn_error: … The specified activity does not exist.

我们已经在REPOS/dav/目录不可由 httpd 进程写入时看到了这一点。检查权限以确保 Apache httpd 可以写入dav/目录(当然也要写入相应的db/目录)。

在 Windows XP 下,Subversion 服务器有时似乎会发送损坏的数据。

您需要安装 Windows XP Service Pack 1 来修复操作系统中的 TCP/IP 堆栈错误。您可以在http://support.microsoft.com/default.aspx?scid=kb;EN-US;q317949.

获取有关该 Service Pack 的所有信息。

在 Subversion 客户端和 Apache 服务器之间的对话中进行网络跟踪的最佳方法是什么?

使用 Ethereal 来窃听对话

注意

  • 以下说明特定于 Ethereal 的图形版本,可能不适用于命令行版本(其二进制文件通常名为 tethereal)。

  • 下拉 Capture 菜单,然后选择 Start。

  • 输入端口 80 作为过滤器,并关闭混杂模式。

  • 运行您的 Subversion 客户端。

  • 点击 Stop。现在您有了捕获。它看起来像一个巨大的行列表。

  • 点击 Protocol 列进行排序。

  • 然后,点击第一条相关的 TCP 行以选中它。

右键点击,然后选择 Follow TCP Stream。您将看到 Subversion 客户端的 HTTP 转换的请求/响应对。或者,您可以在客户端的服务器运行时配置文件中设置一个参数,以使 Neon 的调试输出出现。neon-debug 的数值是NE_DBG_*值在头文件ne_utils.h中的组合。将neon-debug-mask变量设置为 130(即NE_DBG_HTTP + NE_DBG_HTTPBODY

)将导致显示 HTTP 数据。您可能希望在进行网络跟踪时通过调整http-compression

参数来禁用压缩,该参数位于同一个文件中。

我刚刚构建了发行版二进制文件,当我尝试检出 Subversion 时,我收到关于“无法识别的 URL 方案。”的错误。file://Subversion 使用插件系统来允许访问存储库。目前有三个这样的插件:ra_local 允许访问本地存储库,ra_dav 允许通过 WebDAV 访问存储库,ra_svn 允许通过 svnserve 服务器进行本地或远程访问。当您尝试在 Subversion 中执行操作时,程序会尝试根据 URL 方案动态加载插件。AURL 将尝试加载 ra_local,而http://

URL 将尝试加载 ra_dav。您看到的错误意味着动态链接器/加载器找不到要加载的插件。这通常发生在您使用共享库构建 Subversion 然后尝试运行它,而没有先运行 make install 的情况下。另一个可能的原因是您运行了 make install,但库安装在动态链接器/加载器无法识别的位置。在 Linux 下,您可以通过将库目录添加到/etc/ld.so.conf

并运行 ldconfig 来允许链接器/加载器找到库。如果您不想这样做,或者您没有 root 权限,您也可以在 LD_LIBRARY_PATH 环境变量中指定库目录。

为什么 svn revert 命令需要显式目标?为什么它不是默认递归的?此行为与几乎所有其他子命令不同。

简而言之:为了您自己的利益。

Subversion 非常重视保护您的数据,而不仅仅是您的版本化数据。您对已版本化文件的修改以及要添加到版本控制系统的新文件必须小心处理。使 svn revert 命令需要显式目标(即使该目标只是“.”)是实现这一目标的一种方法。此要求(以及在您需要该行为时要求您提供--recursive

标志)旨在让您真正考虑您正在做什么,因为一旦您的文件被还原,您的本地修改将永远消失。

当我启动 Apache 时,mod_dav_svn 会抱怨“数据库版本错误”,它找到了 db-3.X,而不是 db-4.X。

您的 apr-util 与 DB-3 链接,svn 与 DB-4 链接。不幸的是,DB 符号并不不同。当 mod_dav_svn 加载到 Apache 的进程空间时,它最终会解析符号名称以针对 apr-util 的 DB-3 库。

解决方案是确保 apr-util 与 DB-4 编译。您可以通过向 apr-util 或 Apache 的配置传递特定开关来完成此操作:“--with-dbm=db4 --with-berkeley-db=/the/db/prefix”。

我在 RedHat 9 上收到“未实现函数”的错误,没有任何效果。我该如何解决?

这不是 Subversion 的真正问题,但它经常影响 Subversion 用户。

svn: Berkeley DB error
svn: Berkeley DB error while creating environment for filesystem tester/db:
Function not implemented

RedHat 9 和 Fedora 附带一个依赖于内核对 NPTL(Native Posix Threads Library)的支持的 Berkeley DB 库。RedHat 提供的内核内置了此支持,但是如果您自己编译内核,那么您可能没有 NPTL 支持。如果是这种情况,您将看到类似于以下的错误

  • 这可以通过以下几种方法之一来修复

  • 为您的内核重建 db4。

  • 使用 RedHat 9 内核。

  • 将 NPTL 补丁应用于您的内核。

  • 使用包含 NPTL 支持的最新(2.5.x)内核。LD_ASSUME_KERNEL设置为 2.2.5,如果是这样,在启动 Subversion(Apache)之前取消设置它。(通常你应该设置这个变量来在 RedHat 9 上运行 Wine 或 Winex)

为什么日志中显示“(no author)”用于通过 Apache(ra_dav)提交或导入的文件?

如果你允许通过 Apache 匿名写入存储库,Apache 服务器永远不会向客户端验证用户名,而是允许写入操作而无需身份验证。由于 Subversion 不知道是谁进行了操作,因此会导致像这样的日志

$ svn log
------------------------------------------------------------------------
rev 24:  (no author) | 2003-07-29 19:28:35 +0200 (Tue, 29 Jul 2003)
…

阅读有关在 第 6 章,服务器配置 中添加身份验证的信息。

我在 Windows 上偶尔会收到“访问被拒绝”错误。这些错误似乎随机发生。

这些错误似乎是由于各种监视文件系统更改的 Windows 服务(防病毒软件、索引服务、COM+ 事件通知服务)造成的。这并不是 Subversion 的真正错误,这使得它很难修复。有关调查现状的总结,请访问http://www.contactor.se/~dast/svn/archive-2003-10/0136.shtml. 在修订版 7598 中实施了应该减少大多数人出现率的解决方法。

在 FreeBSD 上,某些操作(尤其是 svnadmin create)有时会挂起。

这通常是由于系统上缺乏可用的熵。Subversion 要求 APR 定期生成随机数以创建 UUID,某些操作系统会阻止高质量的随机性。你可能需要配置系统以从诸如硬盘和网络中断之类的来源收集熵。请参考你的系统手册,特别是 random(4)rndcontrol(8),了解如何进行此更改。另一个解决方法是使用/dev/urandom而不是/dev/random.

我可以在 Web 浏览器中看到我的存储库,但是 svn checkout 给出了关于301 Moved Permanently.

的错误,这意味着你的 httpd.conf 配置错误。通常情况下,此错误发生在你的 Subversion 虚拟“location”在同一时间定义在两个不同的范围内时。

例如,如果你将存储库导出为<Location /www/foo>,但你也设置了你的DocumentRoot/www,那么你就遇到了麻烦。当请求进入/www/foo/bar时,Apache 不知道是查找名为/foo/bar真实文件DocumentRoot,还是要求 mod_dav_svn 从/bar存储库中获取文件/www/foo。通常前者会获胜,因此会出现“Moved Permanently”错误。

解决方案是确保你的存储库<Location>不重叠或存在于已导出为普通 Web 共享的任何区域内。

我尝试查看文件的旧版本,但 svn 说“路径未找到”。

Subversion 的一个很好的功能是存储库可以识别复制和重命名,并保留历史连接。例如,如果你将/trunk复制到/branches/mybranch,那么存储库将理解分支中的每个文件都在主干中都有一个“predecessor”。运行 svn log --verbose 将显示历史复制,因此你可以看到重命名

r7932 | joe | 2003-12-03 17:54:02 -0600 (Wed, 03 Dec 2003) | 1 line
Changed paths:
   A /branches/mybranch (from /trunk:7931)

不幸的是,虽然存储库知道复制和重命名,但在 1.0 版中几乎所有 svn 客户端子命令都知道。像 svn diffsvn mergesvn cat 这样的命令应该理解并跟踪重命名,但还没有做到这一点。它被安排为 1.0 之后的特性。例如,如果你要求 svn diff 比较两个较早版本的/branches/mybranch/foo.c,该命令将不会自动理解该任务实际上需要比较两个版本的/trunk/foo.c,因为重命名。相反,你将看到关于分支路径在早期修订版中不存在的错误。

解决所有这类问题的办法是自行进行操作。也就是说:需要了解任何重命名的路径,使用 svn log -v 自己发现它们,然后将它们显式地提供给 svn 客户端。例如,而不是运行

$ svn diff -r 1000:2000 http://host/repos/branches/mybranch/foo.c
svn: Filesystem has no item
svn: '/branches/mybranch/foo.c' not found in the repository at revision 1000

...你应该运行

$ svn diff -r1000:2000 http://host/repos/trunk/foo.c
...


[45] 请记住,你提供有关你的设置和问题的信息量与你从邮件列表中获得答复的可能性成正比。鼓励你包括除你早餐吃了什么和母亲的娘家姓以外的所有信息。

TortoiseSVN 官方中文版 1.14.7 发布