This text is a work in progress—highly subject to change—and may not accurately describe any released version of the Apache™ Subversion® software. Bookmarking or otherwise referring others to this page is probably not such a smart idea. Please visit http://www.svnbook.com/ for stable versions of this book.

文件的可移植性

对于经常需要在不同的操作系统中工作的用户来说, 比较幸运的一点是 Subversion 命令行工具在所有系统中的表现几乎都是相同的, 如果用户已经知道 了如何在一种系统中使用 svn, 那他也就知道了如何在其他 系统中使用 svn.

然而, 其他软件或存放在 Subversion 仓库里的文件并不都是这样. 比如说 在一台 Windows 机器上, 对于 文本文件 的定义和 Linux 机器 类似, 除了一点—标记一行结束的字符序列不同. 除此之外, Unix 平台 (和 Subversion) 支持符号链接, 而 Windows 不支持; Unix 平台根据文件系统权限 来判断文件的可执行性, 而 Windows 是根据文件的扩展名.

Subversion 并不想把整个世界都统一到公共的定义和实现上, 当用户要在多 种不同的操作系统中管理文件与目录时, 它所能做的只是尽量减少用户的麻烦. 本节介绍 Subversion 如何帮助用户在多种不同的平台中使用 Subversion.

文件内容类型

和许多应用程序一样, Subversion 也会使用 MIME (多用途互联网邮件扩展 类型, Multipurpose Internet Mail Extensions) 内容类型. 属性 svn:mime-type 除了可以作为文件内容类型的存放位置, 它的值还决定了 Subversion 的某些行为特征.

比如说, Subversion 提供的一项特性是在更新工作副本时, 支持基于行 的文件内容合并, 但是二进制文件没有 的概念, 于是, 如果文件的 svn:mime-type 属性被设置成非文本 MIME 类型 (非文本的 MIME 类型通常不以 text/ 开始, 但是也有 例外), Subversion 就不会对文件执行合并操作. 作为替代, 如果被更新的二 进制文件含有本地修改, 那文件就不会被更新, Subversion 会另外创建两个 新的文件, 其中一个的扩展名是 .oldrev, 对应文件的 BASE 版本号; 另一个的扩展名是 .newrev, 对应更新 后的版本号. 这样做是为了避免对不支持合并的文件进行合并而带来的错误.

另外, 为了能够以行为单位显示修改, 文件必须能被划分成 , 如果 svn diffsvn annotate 的目标文件的 MIME 类型是非文本的, 这 两个命令默认会报错. 如果用户的文件是 XML 文件, 它们的 svn:mime-type 被设置成 application/xml, 虽然它们是人类可读的文本文件, 但 Subversion 仍然会把它们看成是非文本 文件, 幸好, 为命令添加选项 --force 可以强制 Subversion 不管文件的 MIME 类型, 直接执行操作.

[警告] 警告

如果属性 svn:mime-type 的值不能说明文件内容 是文本的, 这将会给其他属性造成意想不到的影响. 例如, 二进制文件没有 行的概念, 所以 Subversion 不允许为二进制文件设置属性 svn:eol-style. 如果命令的目标是单一的文件, 那么就很 容易看出来—svn propset 会报错退出, 但是, 如果用户递归地执行属性设置命令, 可能就没那么明显了: 如果 Subversion 觉得某个文件不适合设置给定的属性, 它就会悄无声息地跳过该文件.

Subversion 提供了多种机制, 用于自动地设置属性 svn:mime-type, 详细的介绍见 “自动属性设置”一节.

另外, 如果文件设置了属性 svn:mime-type, 响应 GET 请求时, Subversion Apache 模块将会使用属性的值填充 HTTP 头部的 Content-type 字段. 如果用户使用浏览器查看仓库的内容, 这可以提示浏览器应该如何显示文件.

文件的可执行性

在很多操作系统里, 一个文件是否可以执行取决于该文件是否设置了 可执行权限位. 该位默认是不开启的, 如果用户需要可执行权限, 必须显式地 开启它. 但是记住应该为哪些检出的文件设置可执行位是一件很麻烦的事情, 所以 Subversion 提供了属性 svn:executable, 如果文件 设置了该属性, Subversion 就会在工作副本里打开文件的可执行位.

该属性对不支持可执行位的文件系统是没有效果的, 比如 FAT32 和 NTFS. [19] 另外, 尽管该属性 没有预定义的值, 在设置属性时, Subversion 强制把它的值设置为 *. 最后, 该属性只对文件有效, 对目录不起作用.

行结束标记

除非属性 svn:mime-type 进行了额外说明, 否则 Subversion 总是假设文件的内容是人类可读的. 一般来说, Subversion 会根据 自己的知识来判断是否可以对文件进行基于上下文的差异比较, 如果不能的话, 就 按字节比较差异.

Subversion 默认情况下并不关心文件的 行结束 (EOL) 标记 (end-of-line (EOL) markers ) 类型. 不幸的是, 如何结束一行, 不同的操作系统有着不同的约 定. 比如说, Windows 软件使用一对 ASCII 控制字符表示一行的结束— 一个回车符 (CR) 后面再跟一个换行符 (LF ); 而 Unix 系统中的软件只用单一的换行符 (LF ) 表示一行的结束.

如果文件的行结束标记与操作系统的 本地的行结束风格 不同, 有些软件可能无法正确地处理这种文件. 所以在典型情况 下, Unix 程序把来自 Windows 的文件里的回车符 (CR) 当 成一个普通字符 (通常显示成 ^M), 而 Windows 程序会 把来自 Unix 系统的文件显示成一段很长的行, 因为它们找不到用来结束一行 的回车符 (CR).

如果用户要在不同的操作系统之间分享文件, 如此敏感的 EOL 标记可不 是什么好事. 比如说有一个源代码文件, 开发人员可能会同时在 Unix 和 Windows 系统中编辑它, 如果所有开发人员使用的工具都能保留文件原来的行 结束风格, 那就不会产生什么问题.

可惜的是, 如果文件的行结束标记和本地不同, 很多程序要么不能正确地读 取并显示文件, 要么在保存时, 把文件的行结束标记转换成本地风格. 如果是前 一种情况, 开发人员在开始编辑文件之前, 需要使用一种格式转换工具 (比如 dos2unix 及其伙伴 unix2dos) 把 文件的行结束标记转换成本地风格. 如果是后一种情况就不用在编辑之前转换文件 格式. 但是两种情况都会导致文件的每一行都发生变化! 在提交修改之前, 用户 有两种选择, 一是使用格式转换工具把文件的行结束标记转换成与原来一样的 风格, 二是直接提交—使用新的行结束标记.

这种情况的结果是既浪费了时间, 也提交了很多没必要的修改. 浪费时间 已经足够烦人了, 更糟糕的是一次提交修改了文件的每一行, 这会给后面的历史 查询带来很大的麻烦—是哪几行修改解决了问题, 或者是哪一行修改引入 了语法错误.

问题的解决办法是使用属性 svn:eol-style. 如果属 性的值是有效的, Subversion 将根据属性值对文件进行特殊的处理, 这样文件 的行结束风格就不会随着操作系统的变化而变化. 属性的有效值包括:

native

文件的行结束标记是操作系统的本地风格, 换句话说, 如果一个用户 在 Windows 操作系统上检出了工作副本, 文件的 svn:eol-style 被设置成 native, 则文件将使用 CRLF 作为行结束标记. 而 Unix 用户 检出的文件的行结束标记是 LF.

注意, 不管操作系统是什么类型, Subversion 仓库中存放的文件 的行结束标记总是 LF, 这对用户来说是透明的.

CRLF

无论是什么操作系统, 文件总是使用 CRLF 作为行结束标记.

LF

无论是什么操作系统, 文件总是使用 LF 作为 行结束标记.

CR

无论是什么操作系统, 文件总是使用 CR 作为行结束标记. 这种行结束标记用得很少.



[18] 雪上加霜的是, 当时还 有一款叫作 WordPerfect 的软件也使用 .DOC 作为他们的私有文件格式的扩展名!

[19] Windows 的文件系统使用文件的扩展名 (比如 .EXE, .BAT.COM ) 表示文件是可执行的.