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

网络模型

本节将一般性地讨论 Subversion 客户端和服务器如何相互交互,无论您使用哪种网络实现。阅读完本节后,您将对服务器的行为以及客户端配置以响应的不同方式有一个很好的理解。

请求和响应

Subversion 客户端大部分时间都用于管理工作副本。但是,当它需要来自版本库的信息时,它会发出网络请求,而服务器则会以相应的答案进行响应。网络协议的细节对用户隐藏;客户端尝试访问 URL,并且根据 URL 模式,使用特定协议与服务器联系(请参见 版本库 URL)。用户可以运行 svn --version 来查看客户端知道如何使用的 URL 模式和协议。

当服务器进程接收到客户端请求时,它通常要求客户端进行身份验证。它向客户端发出身份验证质询,而客户端则通过向服务器提供 凭据 来响应。一旦身份验证完成,服务器将使用客户端要求的原始信息进行响应。请注意,此系统不同于 CVS 之类的系统,在 CVS 中,客户端在发出任何请求之前都会预先提供凭据(“登录”)给服务器。在 Subversion 中,服务器在适当的时候通过质询客户端来“拉取”凭据,而不是客户端“推送”凭据。这使得某些操作更加优雅。例如,如果服务器配置为允许世界上任何人都读取版本库,那么当客户端尝试 svn checkout 时,服务器将永远不会发出身份验证质询。

如果客户端的网络请求将新数据写入版本库(例如,svn commit),那么将创建新的修订版本树。如果客户端的请求已通过身份验证,则已验证用户的名称将存储为svn:author新修订版本的属性(请参见 名为“未版本控制的属性”的部分)。如果客户端未经身份验证(换句话说,服务器从未发出身份验证质询),则修订版本的svn:author属性为空。[19]

客户端凭据缓存

许多服务器配置为要求对每个请求进行身份验证。这对用户来说可能很烦人,因为他们被迫一遍又一遍地输入密码。

令人欣慰的是,Subversion 客户端为此提供了一种解决办法:一个内置的系统,用于将身份验证凭据缓存到磁盘上。默认情况下,每当命令行客户端成功地向服务器进行身份验证时,它会将凭据保存在用户的私有运行时配置区域中,即~/.subversion/auth/在类 Unix 系统上,或者%APPDATA%/Subversion/auth/在 Windows 上。(运行时区域将在 名为“运行时配置区域”的部分中更详细地介绍。)成功凭据将缓存到磁盘上,并根据主机名、端口和身份验证域的组合进行键控。

当客户端收到身份验证质询时,它首先会在磁盘缓存中查找相应的凭据;如果不存在,或者如果缓存的凭据无法进行身份验证,则客户端会简单地提示用户提供信息。

那些对安全性感到担忧的人可能会想:“将密码缓存到磁盘上?那太糟糕了!你不应该那样做!” 但请保持冷静。首先,auth/缓存区域受权限保护,因此只有用户(所有者)可以从中读取数据,而不是世界上的任何人都可以读取。如果您仍然认为这还不够安全,您可以禁用凭据缓存。要禁用单个命令的缓存,请传递--no-auth-cache选项

$ svn commit -F log_msg.txt --no-auth-cache
Authentication realm: <svn://host.example.com:3690> example realm
Username:  joe
Password for 'joe':

Adding         newfile
Transmitting file data .
Committed revision 2324.

# password was not cached, so a second commit still prompts us

$ svn delete newfile
$ svn commit -F new_msg.txt
Authentication realm: <svn://host.example.com:3690> example realm
Username:  joe
[...]

或者,如果您想永久禁用凭据缓存,您可以编辑运行时config文件(位于auth/目录旁边)。只需将store-auth-creds设置为no,则永远不会将凭据缓存到磁盘上。

[auth]
store-auth-creds = no

有时,用户可能想要从磁盘缓存中删除特定的凭据。要做到这一点,您需要导航到auth/区域并手动删除相应的缓存文件。凭据将缓存到单个文件中;如果您查看每个文件内部,您将看到键和值。该svn:realmstring键描述了与文件关联的特定服务器域

$ ls ~/.subversion/auth/svn.simple/
5671adf2865e267db74f09ba6f872c28        
3893ed123b39500bca8a0b382839198e
5c3c22968347b390f349ff340196ed39

$ cat ~/.subversion/auth/svn.simple/5671adf2865e267db74f09ba6f872c28

K 8
username
V 3
joe
K 8
password
V 4
blah
K 15
svn:realmstring
V 45
<https://svn.domain.com:443> Joe's repository
END

找到正确的缓存文件后,只需将其删除即可。

关于客户端身份验证行为的最后一点:需要对--username--password选项进行一些解释。许多客户端子命令都接受这些选项;但是,了解使用这些选项不会自动将凭据发送到服务器非常重要。如前所述,服务器在认为必要时从客户端“拉取”凭据;客户端不能随意“推送”它们。如果以选项形式传递用户名和/或密码,则只有在服务器请求时才会将其呈现给服务器。[20] 通常,当

  • 用户希望以与其系统登录名不同的用户身份进行身份验证时,或者

  • 脚本希望在不使用缓存凭据的情况下进行身份验证时,会使用这些选项。

以下是描述 Subversion 客户端在收到身份验证质询时如何执行操作的最终摘要

  1. 检查用户是否通过命令行选项指定了任何凭据,方法是使用--username和/或--password. 如果没有,或者这些选项无法成功进行身份验证,则

  2. 在运行时查找服务器的域auth/区域,以查看用户是否已缓存了相应的凭据。如果没有,或者如果缓存的凭据无法进行身份验证,则

  3. 使用提示用户的方式。

如果客户端通过上述任何方法成功地进行了身份验证,它将尝试将凭据缓存到磁盘上(除非用户禁用了此行为,如前所述)。



[19] 此问题实际上是一个常见问题,是由于服务器设置配置错误导致的。

[20] 同样,一个常见的错误是错误地配置服务器,使其永远不会发出身份验证质询。当用户将--username--password选项传递给客户端时,他们会惊讶地发现这些选项从未使用过,也就是说,新修订版本似乎仍然以匿名方式提交了!

TortoiseSVN 官方中文版 1.14.7 发布