本文档仍在编写中,内容可能随时变更,可能无法准确描述任何已发布的 Apache™ Subversion® 软件版本。为避免混乱,请勿将此页面添加书签或推荐给他人。请访问 https://svnbooks.subversion.org.cn/ 查看本书的稳定版本。
对于那些经常在不同操作系统上使用不同计算机的 Subversion 用户来说,幸运的是,Subversion 的命令行程序在所有这些系统上的行为几乎完全相同。如果你知道如何在某个平台上使用 svn,那么你就可以在任何地方使用它。
然而,其他通用软件类别或您在 Subversion 中保存的实际文件的行为并不总是如此。例如,在 Windows 机器上,“文本文件” 的定义类似于 Linux 机器上的定义,但存在一个关键区别——用于标记这些文件行尾的字符序列。还有其他差异。Unix 平台拥有(并且 Subversion 支持)符号链接;Windows 没有。Unix 平台使用文件系统权限来确定可执行性;Windows 使用文件名扩展名。
由于 Subversion 无法在所有这些方面统一全世界,因此它能做的最好的事情就是尝试在您需要在多台计算机和操作系统上处理版本控制的文件和目录时,让您的生活更轻松。本节描述了 Subversion 实现此目标的一些方法。
Subversion 加入了许多识别和使用多用途互联网邮件扩展 (MIME) 内容类型的应用程序的行列。除了作为文件内容类型的一般用途存储位置之外,svn:mime-type
文件属性的值还决定了 Subversion 本身的一些行为特征。
例如,Subversion 通常提供的好处之一是,在更新期间,将从服务器接收到的更改以上下文方式、基于行地合并到您的工作文件中。但对于包含非文本数据的文件,通常不存在 “行” 的概念。因此,对于 svn:mime-type
属性设置为非文本 MIME 类型(通常,以 text/
开头的 MIME 类型除外,尽管存在例外)的版本控制文件,Subversion 不会尝试在更新期间执行上下文合并。相反,无论何时您在本地修改了也正在更新的二进制工作副本文件,您的文件将保持不变,Subversion 会创建两个新文件。一个文件带有 .oldrev
扩展名,包含文件的 BASE 修订版。另一个文件带有 .newrev
扩展名,包含更新的修订版文件的內容。此行为实际上是为了保护用户,防止在无法上下文合并的文件上尝试执行上下文合并时出现错误。
此外,由于显示基于行的差异和基于行的更改归属的行為显然依赖于对给定文件存在 “行” 的有意义定义,因此,默认情况下,具有非文本 MIME 类型的文件在用作 svn diff 和 svn annotate 操作的目标时会触发错误。这对于使用 XML 文件的用户来说尤其令人沮丧,这些文件的 svn:mime-type
属性设置为 application/xml
之类的内容,这种内容并非明确的人可读的,因此被 Subversion 视为非文本的。幸运的是,这些子命令提供了 --force
选项,用于强制 Subversion 尝试执行操作,尽管文件明显不是人可读的。
警告 | |
---|---|
当 |
Subversion 提供了一些机制,可以通过这些机制自动在版本控制的文件上设置 svn:mime-type
属性。有关详细信息,请参阅“自动属性设置”部分。
此外,如果设置了 svn:mime-type
属性,则 Subversion Apache 模块将使用其值在响应 GET 请求时填充 Content-type:
HTTP 标头。这为您的 Web 浏览器提供了一个重要的线索,告诉它如何在您使用它来浏览 Subversion 存储库的内容时显示文件。
在许多操作系统上,将文件作为命令执行的能力取决于是否存在执行权限位。此位通常默认禁用,并且必须由用户为每个需要它的文件显式启用。但是,记住哪些刚检出的工作副本中的文件应该启用其可执行位,然后进行切换,将是一件非常麻烦的事情。因此,Subversion 提供了 svn:executable
属性,作为一种方法来指定应该启用设置了该属性的文件的可执行位,并且 Subversion 在使用此类文件填充工作副本时会尊重此请求。
此属性对没有可执行权限位概念的文件系统(例如 FAT32 和 NTFS)没有影响。[20] 此外,虽然此属性没有定义的值,但 Subversion 在设置此属性时会将其值强制为 *
。最后,此属性仅对文件有效,对目录无效。
除非使用版本控制文件的 svn:mime-type
属性另行说明,否则 Subversion 假设文件包含人可读数据。一般来说,Subversion 仅使用此知识来确定该文件的上下文差异报告是否可行。否则,对于 Subversion 来说,字节就是字节。
这意味着,默认情况下,Subversion 不理会您文件中使用的 行尾 (EOL) 标记 的类型。不幸的是,不同的操作系统对哪些字符序列表示文件中的文本行尾有不同的约定。例如,Windows 平台上的软件通常使用的行尾标记是一个 ASCII 控制字符对——回车符 (CR
) 后跟换行符 (LF
)。然而,Unix 软件仅使用 LF
字符来表示行尾。
并非所有这些操作系统上的各种工具都理解包含以与运行它们的 operating system 的 本机行尾样式 不同的格式表示的行尾的文件。因此,通常情况下,Unix 程序将 Windows 文件中出现的 CR
字符视为普通字符(通常呈现为 ^M
),而 Windows 程序将 Unix 文件中的所有行合并为一行,因为没有找到 CR
字符来表示行尾。
这种对外国 EOL 标记的敏感性对于那些在不同操作系统之间共享文件的人来说可能令人沮丧。例如,考虑一个源代码文件,以及在 Windows 和 Unix 系统上编辑此文件的开发人员。如果所有开发人员始终使用保留文件行尾样式的工具,就不会出现问题。
但在实践中,许多常见的工具要么无法正确读取包含外国 EOL 标记的文件,要么在保存文件时将文件的行尾转换为本机样式。如果对于某个开发人员来说,前者是正确的,那么他必须使用外部转换实用程序(例如 dos2unix 或其配套工具 unix2dos)来准备文件进行编辑。后者不需要额外的准备。但这两种情况都会导致文件与原始文件不同,从字面上看,每行都不同!在提交更改之前,用户有两种选择。要么他可以使用转换实用程序将修改后的文件恢复到与编辑前相同的行尾样式,要么他可以简单地提交文件——新的 EOL 标记和所有内容。
这种场景的结果包括浪费时间和对已提交文件的无谓修改。浪费时间已经够痛苦了。但当提交更改文件中的每一行时,这会让确定哪些行发生了非平凡的更改变得复杂。那个 bug 到底在哪里修复的?哪一行引入了语法错误?
解决这个问题的方法是 svn:eol-style
属性。当该属性设置为有效值时,Subversion 会使用它来确定对文件执行哪些特殊处理,以便文件的行尾样式不会随着来自不同操作系统的每次提交而发生变化。有效值是
native
这会导致文件包含运行 Subversion 的操作系统本地的 EOL 标记。换句话说,如果 Windows 上的用户检出一个包含 svn:eol-style
属性设置为 native
的文件的版本库,该文件将包含 CRLF
EOL 标记。Unix 用户检出一个包含相同文件的版本库,将在该文件的副本中看到 LF
EOL 标记。
请注意,Subversion 实际上会使用规范化的 LF
EOL 标记将文件存储在版本库中,无论操作系统是什么。这对用户来说基本上是透明的。
CRLF
这会导致文件包含 CRLF
序列作为 EOL 标记,无论使用什么操作系统。
LF
这会导致文件包含 LF
字符作为 EOL 标记,无论使用什么操作系统。
CR
这会导致文件包含 CR
字符作为 EOL 标记,无论使用什么操作系统。这种行尾样式并不常见。