本文档旨在描述 Apache™ Subversion® 的 1.7.x 系列。如果您运行的是其他版本的 Subversion,强烈建议您访问 https://svnbook.subversion.org.cn/ 并查阅适合您 Subversion 版本的文档。

文件可移植性

对于经常在不同操作系统上使用不同计算机的 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/ 开头的类型,尽管存在例外)的版本化文件,Subversion 不会尝试在更新期间执行上下文合并。相反,任何时候您在本地修改了也正在更新的二进制工作副本文件,您的文件将保持不变,Subversion 将创建两个新文件。一个文件具有 .oldrev 扩展名,包含文件的 BASE 修订版。另一个文件具有 .newrev 扩展名,包含更新的修订版的文件内容。这种行为实际上是为了保护用户免受对无法上下文合并的文件执行上下文合并的失败尝试。

此外,由于显示基于行的差异和基于行的更改归属的行为显然依赖于对给定文件存在 的有意义定义,因此具有非文本 MIME 类型的文件在默认情况下将触发错误,当用作 svn diffsvn annotate 操作的目标时。这对于具有其 svn:mime-type 属性设置为诸如 application/xml 之类的 XML 文件的用户来说尤其令人沮丧,这些文件并非明确地可读,因此被 Subversion 视为非文本。幸运的是,这些子命令提供了一个 --force 选项,用于强制 Subversion 尝试执行操作,尽管文件明显不可读。

[Warning] 警告

svn:mime-type 属性设置为不指示文本文件内容的值时,它可能会导致与其他属性相关的某些意外行为。例如,由于行结束符(因此,行结束符转换)的概念在应用于非文本文件时毫无意义,因此 Subversion 将阻止您在这些文件上设置 svn:eol-style 属性。当尝试在单个文件目标上执行此操作时,这一点很明显——svn propset 将出错。但如果您执行递归属性设置,则可能不太清楚,在这种情况下,Subversion 将静默地跳过它认为不适合给定属性的文件。

Subversion 提供了许多机制,用于自动在版本化文件上设置 svn:mime-type 属性。有关详细信息,请参阅 名为“自动属性设置”的部分

此外,如果设置了 svn:mime-type 属性,则 Subversion Apache 模块将使用其值来填充 Content-type: HTTP 标头,以响应 GET 请求。当您使用它来浏览 Subversion 存储库的内容时,这会为您的 Web 浏览器提供关于如何显示文件的关键线索。

文件可执行性

在许多操作系统上,将文件作为命令执行的能力由一个执行权限位控制。此位通常默认情况下处于禁用状态,用户必须为每个需要它的文件显式启用它。但要记住刚检出的工作副本中哪些文件应该启用其可执行位,然后进行切换,这将是一件非常麻烦的事情。因此,Subversion 提供了 svn:executable 属性,作为一种方法来指定应该启用设置该属性的文件的可执行位,Subversion 在使用此类文件填充工作副本时会遵守此请求。

此属性对没有可执行权限位概念的文件系统没有影响,例如 FAT32 和 NTFS。[17] 此外,虽然它没有定义的值,但 Subversion 在设置此属性时会将其值强制为 *。最后,此属性仅对文件有效,对目录无效。

行尾字符序列

除非使用版本控制文件的 svn:mime-type 属性另有说明,否则 Subversion 假设文件包含人类可读的数据。一般来说,Subversion 仅使用此知识来确定该文件的上下文差异报告是否可行。否则,对 Subversion 来说,字节就是字节。

这意味着默认情况下,Subversion 不关注文件中使用的 行尾 (EOL) 标记 类型。不幸的是,不同的操作系统对哪些字符序列表示文件中的文本行尾有不同的约定。例如,Windows 平台上的软件通常使用的行尾标记是两个 ASCII 控制字符——回车 (CR) 后跟换行 (LF)。然而,Unix 软件只使用 LF 字符来表示行尾。

并非所有这些操作系统上的各种工具都理解包含与运行它们的系统的 本机行尾样式 不同的格式的行尾的文件。因此,通常情况下,Unix 程序将 Windows 文件中存在的 CR 字符视为普通字符(通常呈现为 ^M),而 Windows 程序将 Unix 文件的所有行合并为一行,因为没有找到回车-换行(或 CRLF)字符组合来表示行尾。

这种对外国 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 标记,无论使用的是哪种操作系统。这种行尾样式并不常见。



[16] 你觉得这很糟糕?在那个时代,WordPerfect 也使用 .DOC 作为其专有文件格式的首选扩展名!

[17] Windows 文件系统使用文件扩展名(例如 .EXE.BAT.COM)来表示可执行文件。

TortoiseSVN 官方中文版 1.14.7 发布