这份文档是用来描述 Subversion 1.1 的。如果你正在运行一个更新版本的 Subversion,我们强烈建议你访问 https://svnbooks.subversion.org.cn/ 并查阅与你的 Subversion 版本匹配的书籍版本。
我们已经详细地介绍了 Subversion 如何在其仓库中存储和检索文件的各种版本。整个章节都致力于这个由工具提供的最基本的功能。如果版本控制支持到此为止,从版本控制的角度来看,Subversion 仍然是完整的。但它并没有止步于此。
除了对你的目录和文件进行版本控制,Subversion 还提供了接口,用于在你的每个版本化目录和文件上添加、修改和删除版本化元数据。我们将这种元数据称为 属性,可以将其视为将属性名称映射到附加到工作副本中每个项目上的任意值的双列表格。一般来说,属性的名称和值可以是任何你想要的,前提是名称必须是人类可读的文本。这些属性的最佳之处在于它们也是版本化的,就像你的文件的文本内容一样。你可以像提交文本更改一样轻松地修改、提交和恢复属性更改。当你更新你的工作副本时,你也会收到其他人对属性的更改。
在本节中,我们将研究属性支持的效用——对 Subversion 用户和 Subversion 本身都有用。你将了解与属性相关的 svn 子命令,以及属性修改如何影响你的正常 Subversion 工作流程。希望你能相信 Subversion 属性可以增强你的版本控制体验。
属性可以作为工作副本的非常有用的补充。事实上,Subversion 本身使用属性来容纳特殊信息,以及作为表示需要执行某些特殊处理的方式。同样地,你可以将属性用于你自己的目的。当然,你可以使用常规的版本化文件完成使用属性可以做到的任何事情,但请考虑以下 Subversion 属性使用的示例。
假设你想要设计一个网站,该网站包含许多数字照片,并以标题和时间戳的形式显示它们。现在,你的照片集在不断变化,因此你希望尽可能地自动化这个网站。这些照片可能非常大,因此正如这种性质的网站通常那样,你希望为你的网站访问者提供更小的缩略图。你可以使用传统的文件来实现。也就是说,你可以有你的image123.jpg以及一个image123-thumbnail.jpg并排放在一个目录中。或者,如果你想保持文件名相同,你可以在另一个目录中保存你的缩略图,比如thumbnails/image123.jpg。你也可以以类似的方式存储你的标题和时间戳,再次与原始图像文件分开。很快,你的文件树就会变得一团糟,并且随着添加到网站上的每张新照片而呈倍数增长。
现在考虑使用 Subversion 的文件属性进行相同的设置。想象一下,你有一个单独的图像文件,image123.jpg,然后在该文件上设置名为caption, datestamp,甚至thumbnail的属性。现在你的工作副本目录看起来更易于管理——事实上,它看起来就像里面只有图像文件。但是你的自动化脚本对此了如指掌。他们知道可以使用 svn(或者更好的是,可以使用 Subversion 语言绑定——参见 名为“使用除 C 和 C++ 之外的语言”的部分)来挖掘你的网站需要显示的额外信息,而无需读取索引文件或玩路径操作游戏。
如何(以及是否)使用 Subversion 属性由你决定。正如我们提到的,Subversion 对属性有自己的用途,我们将在本章稍后讨论。但首先,让我们讨论如何使用 svn 程序来操作选项。
svn 命令提供了几种添加或修改文件和目录属性的方法。对于具有简短、人类可读值的属性,添加新属性最简单的方法可能是指定属性名称和值在 propset 子命令的命令行上。
$ svn propset copyright '(c) 2003 Red-Bean Software' calc/button.c property 'copyright' set on 'calc/button.c' $
但是我们一直在宣传 Subversion 为你的属性值提供的灵活性。如果你打算使用多行文本,甚至二进制的属性值,你可能不希望在命令行上提供该值。因此,propset 子命令采用--file (-F)选项来指定包含新属性值的的文件名称。
$ svn propset license -F /path/to/LICENSE calc/button.c property 'license' set on 'calc/button.c' $
除了 propset 命令,svn 程序还提供 propedit 命令。此命令使用配置的编辑器程序(参见 名为“配置”的部分)来添加或修改属性。当你运行此命令时,svn 将在包含属性当前值的临时文件(或者如果要添加新属性,则为空)上调用你的编辑器程序。然后,你只需在编辑器程序中修改该值,直到它表示你希望存储在属性中的新值,保存临时文件,然后退出编辑器程序。如果 Subversion 检测到你实际上更改了属性的现有值,它将接受该值作为新的属性值。如果你在没有进行任何更改的情况下退出编辑器,则不会进行任何属性修改。
$ svn propedit copyright calc/button.c ### exit the editor without changes No changes to property 'copyright' on 'calc/button.c' $
我们应该注意,与其他 svn 子命令一样,与属性相关的那些子命令可以同时作用于多个路径。这使你能够使用单个命令修改整组文件的属性。例如,我们可以执行以下操作:
$ svn propset copyright '(c) 2002 Red-Bean Software' calc/* property 'copyright' set on 'calc/Makefile' property 'copyright' set on 'calc/button.c' property 'copyright' set on 'calc/integer.c' … $
如果你无法轻松地获取存储的属性值,那么所有这些属性添加和编辑实际上并没有多大用处。因此,svn 程序提供了两个用于显示存储在文件和目录上的属性的名称和值的子命令。 svn proplist 命令将列出存在于路径上的属性的名称。一旦你知道了节点上的属性的名称,你就可以使用 svn propget 单独请求它们的值。此命令将在给定路径(或路径集)和属性名称的情况下,将属性的值打印到标准输出流。
$ svn proplist calc/button.c Properties on 'calc/button.c': copyright license $ svn propget copyright calc/button.c (c) 2003 Red-Bean Software
甚至有一个 proplist 命令的变体,它将列出所有属性的名称和值。只需提供--verbose (-v)选项。
$ svn proplist --verbose calc/button.c Properties on 'calc/button.c': copyright : (c) 2003 Red-Bean Software license : ================================================================ Copyright (c) 2003 Red-Bean Software. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the recipe for Fitz's famous red-beans-and-rice. …
最后一个与属性相关的子命令是 propdel。由于 Subversion 允许你存储具有空值的属性,因此你无法使用 propedit 或 propset 完全删除属性。例如,此命令将 不会产生预期效果:
$ svn propset license '' calc/button.c property 'license' set on 'calc/button.c' $ svn proplist --verbose calc/button.c Properties on 'calc/button.c': copyright : (c) 2003 Red-Bean Software license : $
你需要使用 propdel 命令才能完全删除属性。语法与其他属性命令类似:
$ svn propdel license calc/button.c property 'license' deleted from ''. $ svn proplist --verbose calc/button.c Properties on 'calc/button.c': copyright : (c) 2003 Red-Bean Software $
既然你已经熟悉了所有与属性相关的 svn 子命令,让我们看看属性修改如何影响通常的 Subversion 工作流程。正如我们之前提到的,文件和目录属性是版本化的,就像你的文件内容一样。因此,Subversion 提供了相同的合并机会——以干净或冲突的方式——将其他人的修改合并到你的修改中。
与文件内容一样,你的属性更改是本地修改,只有在使用 svn commit 将它们提交到仓库后才会永久生效。你的属性更改也可以轻松地撤销——svn revert 命令将使你的文件和目录恢复到未编辑状态,内容、属性,以及所有内容。此外,你可以使用 svn status 和 svn diff 命令获得有关文件和目录属性状态的有趣信息。
$ svn status calc/button.c M calc/button.c $ svn diff calc/button.c Property changes on: calc/button.c ___________________________________________________________________ Name: copyright + (c) 2003 Red-Bean Software $
注意,status 子命令如何在第二列而不是第一列中显示M。这是因为我们修改了calc/button.c上的属性,但没有修改它的文本内容。如果我们同时更改了这两者,我们也会在第一列中看到M(参见 名为“svn status”的部分)。
你可能还注意到 Subversion 目前显示属性差异的非标准方式。你仍然可以运行 svn diff 并将输出重定向以创建一个可用的补丁文件。 patch 程序将忽略属性补丁——作为一项规则,它将忽略它无法理解的任何噪音。这确实意味着要完全应用由 svn diff 生成的补丁,任何属性修改都需要手动应用。
如您所见,属性修改的存在对典型的 Subversion 工作流程没有显着影响。您更新工作副本、检查文件和目录状态、报告所做的修改以及将这些修改提交到存储库的一般模式,完全不受属性存在与否的影响。svn 程序有一些额外的子命令用于实际进行属性更改,但这只是唯一明显的差异。
Subversion 对属性没有特定的策略——您可以将它们用于任何目的。Subversion 仅要求您不要使用以以下前缀开头的属性名称:svn. 这是它为自身使用而保留的命名空间。实际上,Subversion 定义了某些属性,这些属性对它们所附加的文件和目录具有神奇的效果。在本节中,我们将解开谜团,并描述这些特殊属性如何让您的生活更加轻松。
该svn:executable属性用于以半自动方式控制版本控制文件的文件系统级执行权限位。此属性没有定义的值——它的存在表示希望 Subversion 保持执行权限位启用。删除此属性将恢复操作系统对执行位的完全控制。
在许多操作系统上,将文件作为命令执行的能力由执行权限位的存在来决定。此位通常默认为禁用状态,并且必须由用户为每个需要它的文件显式启用。在工作副本中,新文件会不断创建,因为在更新期间会收到现有文件的最新版本。这意味着您可能已在某个文件上启用了执行位,然后更新了您的工作副本,如果该文件在更新过程中发生了更改,则它的执行位可能会被禁用。因此,Subversion 提供了svn:executable属性作为一种保持执行位启用的方法。
此属性对没有可执行权限位概念的文件系统(如 FAT32 和 NTFS)没有影响。[28] 此外,虽然它没有定义的值,但 Subversion 会将其值强制设置为*在设置此属性时。最后,此属性仅对文件有效,而不对目录有效。
该svn:mime-type属性在 Subversion 中起着多种作用。除了作为文件的多用途互联网邮件扩展 (MIME) 分类的一般用途存储位置之外,此属性的值还会确定 Subversion 本身的某些行为特征。
例如,如果文件的svn:mime-type属性设置为非文本 MIME 类型(通常,不以text/开头,尽管存在例外),Subversion 将假定该文件包含二进制数据,即不可读数据。Subversion 通常提供的好处之一是,在更新期间,从服务器接收到的更改的上下文、基于行的合并到您的工作文件中。但是,对于被认为包含二进制数据的文件,没有“行”的概念。因此,对于这些文件,Subversion 不会尝试在更新期间执行上下文合并。相反,如果您在也正在更新的二进制工作副本文件中进行了本地修改,则您的文件将被重命名并带有.orig扩展名,然后 Subversion 将存储一个新的工作副本文件,该文件包含在更新期间接收的更改,但不包含您自己的本地修改,并且使用原始文件名。此行为实际上是为了保护用户免受在无法进行上下文合并的文件上执行上下文合并的失败尝试的侵害。
此外,如果svn:mime-type属性已设置,则 Subversion Apache 模块将使用其值来填充Content-typeHTTP 标头,以响应 GET 请求。这为使用 Web 浏览器浏览存储库时如何显示文件提供了一个重要的线索。
该svn:ignore属性包含一些文件模式列表,Subversion 的某些操作将忽略这些模式。它可能是最常用的特殊属性,它与global-ignores运行时配置选项(参见 名为“Config”的部分)一起使用,以从 svn status、svn add 和 svn import 命令中过滤掉未版本控制的文件和目录。
背后的基本原理svn:ignore属性很容易解释。Subversion 不假定工作副本目录中的每个文件或子目录都适合版本控制。必须使用 svn add 或 svn import 命令显式地将资源置于 Subversion 的管理之下。因此,工作副本中通常有许多资源未版本控制。
现在,svn status 命令将其输出的一部分显示为工作副本中每个未版本控制的文件或子目录,这些文件或子目录尚未被global-ignores选项(或其内置默认值)过滤掉。这样做是为了让用户能够看到是否忘记将资源添加到版本控制中。
但是 Subversion 无法猜测应该忽略的每个资源的名称。此外,在特定存储库的每个工作副本中,经常会有很多东西应该被忽略。强制每个使用该存储库的用户将其运行时配置区域中的资源模式添加到他们的运行时配置区域中,不仅会带来负担,而且还可能与用户签出的其他工作副本的配置需求发生冲突。
解决方案是将可能出现在给定目录中的资源的唯一忽略模式存储在该目录本身中。未版本控制资源的常见示例(这些资源基本上是特定于目录的,但很可能出现在那里)包括程序编译的输出。或者,为了使用更适合本书的示例,可以将一些源 DocBook XML 文件转换为更易读的输出格式而生成的 HTML、PDF 或 PostScript 文件。
为此目的,svn:ignore属性是解决方案。它的值是文件模式的多行集合,每行一个模式。该属性是在您希望应用模式的目录上设置的。[29] 例如,假设您有以下 svn status 的输出
$ svn status calc M calc/button.c ? calc/calculator ? calc/data.c ? calc/debug_log ? calc/debug_log.1 ? calc/debug_log.2.gz ? calc/debug_log.3.gz
在此示例中,您对button.c进行了一些属性修改,但在您的工作副本中,您还有一些未版本控制的文件:您从源代码编译的最新calculator程序,一个名为data.c的源文件,以及一组调试输出日志文件。现在,您知道您的构建系统始终会生成calculator程序。[30] 并且您知道您的测试套件始终会留下这些调试日志文件。这些事实适用于所有工作副本,而不仅仅是您自己的副本。而且您知道您不希望每次运行 svn status 时都看到这些东西。因此,您使用 svn propedit svn:ignore calc 将一些忽略模式添加到calc目录中。例如,您可能会添加以下内容作为svn:ignore属性的新的值
calculator debug_log*
添加此属性后,您现在将在calc目录上有一个本地属性修改。但请注意,您的 svn status 输出还有哪些不同之处
$ svn status M calc M calc/button.c ? calc/data.c
现在,所有杂乱无章的东西都从输出中消失了!当然,这些文件仍然存在于您的工作副本中。Subversion 只是没有提醒您它们存在并且未版本控制。现在,所有无关紧要的噪声都从显示中消失了,您剩下的是更有趣的东西——比如您可能忘记添加到版本控制的源代码文件。
如果您想查看被忽略的文件,可以将--no-ignore选项传递给 Subversion
$ svn status --no-ignore M calc/button.c I calc/calculator ? calc/data.c I calc/debug_log I calc/debug_log.1 I calc/debug_log.2.gz I calc/debug_log.3.gz
忽略模式列表还被 svn add 和 svn import 使用。这两个操作都涉及让 Subversion 开始管理一组文件和目录。Subversion 不会强迫用户选择要开始版本控制的树中的哪些文件,而是使用忽略模式来确定哪些文件不应该作为更大的递归添加或导入操作的一部分而被纳入版本控制系统。
Subversion 能够将关键字(有关版本控制文件的有用动态信息)替换到文件本身的内容中。关键字通常描述有关文件上次已知修改时间的的信息。由于此信息会在每次文件更改时发生变化,更重要的是,会在文件更改之后发生变化,因此,除了版本控制系统之外的任何流程都难以使数据完全保持最新。如果留给人类作者,这些信息将不可避免地变得过时。
例如,假设您有一个文档,您希望在其中显示该文档上次修改的日期。您可以让该文档的每个作者在提交更改之前,还调整描述上次更改时间的文档部分。但迟早会有人忘记这样做。相反,只需让 Subversion 对LastChangedDate关键字执行关键字替换即可。您通过在文件中所需位置放置一个关键字锚来控制关键字插入的位置。此锚点只是一串文本,格式为$KeywordName$.
所有关键字在文件中作为锚点出现时都区分大小写:您必须使用正确的首字母大写才能扩展关键字。您应该将svn:keywords属性的值也视为区分大小写的——某些关键字名称将被识别,无论大小写如何,但此行为已过时。
Subversion 定义了可用于替换的关键字列表。该列表包含以下五个关键字,其中一些关键字有别名,您也可以使用这些别名
此关键字描述文件上次在存储库中已知发生更改的时间,看起来像$Date: 2002-07-22 21:42:37 -0700 (Mon, 22 Jul 2002) $. 它也可以指定为LastChangedDate.
此关键字描述文件在存储库中最后一次已知更改的修订版本,看起来像$Revision: 144 $. 它也可以指定为LastChangedRevision或Rev.
此关键字描述上次已知更改该文件的用户,看起来像$Author: harry $. 它也可以指定为LastChangedBy.
此关键字描述存储库中该文件的最新版本的完整 URL,看起来像$HeadURL: http://svn.collab.net/repos/trunk/README $. 它可以缩写为URL.
这个关键字是其他关键字的压缩组合。它的替换看起来像$Id: calc.c 148 2002-07-28 21:30:43Z sally $,它表示该文件calc.c最后一次修改是在 2002 年 7 月 28 日晚上,由用户sally.
修改,版本号为 148。
仅仅在您的文件中添加关键字锚文本不会有任何特殊效果。除非您明确要求,否则 Subversion 永远不会尝试对您的文件内容进行文本替换。毕竟,您可能正在编写一份关于如何使用关键字的文档[31],您不希望 Subversion 替换您精心编写的未替换关键字锚文本的示例!svn:keywords要告诉 Subversion 是否在特定文件上替换关键字,我们再次使用与属性相关的子命令。该
属性在版本化文件上设置时,控制将在该文件上替换哪些关键字。该值是前面表格中找到的关键字名称或别名的空格分隔列表。例如,假设您有一个名为weather.txt
Here is the latest report from the front lines. $LastChangedDate$ $Rev$ Cumulus clouds are appearing more frequently as summer approaches.
的版本化文件,其内容如下:svn:keywords如果该文件没有设置LastChangedDate属性,Subversion 不会执行任何特殊操作。现在,让我们启用
$ svn propset svn:keywords "Date Author" weather.txt property 'svn:keywords' set on 'weather.txt' $
关键字的替换。例如,假设您有一个名为现在,您对该Rev文件进行了本地属性修改。您将不会看到文件内容的任何更改(除非您在设置属性之前进行了一些自己的更改)。请注意,该文件包含svn:keywords关键字的关键字锚文本,但我们没有将该关键字包含在我们设置的属性值中。Subversion 会很乐意忽略替换文件中不存在的关键字的请求,并且不会替换
关键字替换对用户的可见结果可能会让您认为,使用该功能的每个文件版本在至少放置关键字锚文本的区域与前一个版本不同。但是,实际上并非如此。在 svn diff 检查本地修改时,以及在 svn commit 传输这些本地修改之前,Subversion 会“取消替换”之前替换的任何关键字。这样一来,存储在仓库中的文件版本只包含用户对文件进行的真实修改。在您提交此属性更改后,Subversion 会使用新的替换文本更新您的工作文件。您将不再看到关键字锚文本$LastChangedDate$$,而是看到其替换结果。该结果还包含关键字的名称,并继续用美元符号 (Rev) 字符括起来。正如我们预测的那样,
关键字没有被替换,因为我们没有要求替换它。svn:keywords另外请注意,我们将在您提交此属性更改后,Subversion 会使用新的替换文本更新您的工作文件。您将不再看到关键字锚文本属性设置为“Date Author”,但关键字锚文本使用了别名
Here is the latest report from the front lines. $LastChangedDate: 2002-07-22 21:42:37 -0700 (Mon, 22 Jul 2002) $ $Rev$ Cumulus clouds are appearing more frequently as summer approaches.
,并且仍然正确地扩展了。例如,假设您有一个名为如果现在其他人提交了对例如,假设您有一个名为的更改,您对该文件的副本将继续显示与之前相同的替换关键字值,直到您更新工作副本。届时,您
svn:eol-stylesvn:mime-type除非使用版本化文件的
属性另有说明,否则 Subversion 假设该文件包含人类可读的数据。一般来说,Subversion 只使用此信息来确定该文件的上下文差异报告是否可行。否则,对 Subversion 来说,字节就是字节。这意味着,默认情况下,Subversion 不会注意您的文件中使用的 行结束标记 类型。不幸的是,不同的操作系统使用不同的标记来表示文件中的文本行结束。例如,Windows 平台上的软件通常使用的行结束标记是两个 ASCII 控制字符——回车 (CR) 和换行 (LF) 和换行 ()。但是,Unix 软件只使用
字符来表示行结束。这意味着,默认情况下,Subversion 不会注意您的文件中使用的 行结束标记 类型。不幸的是,不同的操作系统使用不同的标记来表示文件中的文本行结束。例如,Windows 平台上的软件通常使用的行结束标记是两个 ASCII 控制字符——回车 (并非所有这些操作系统上的各种工具都准备好了理解包含与运行它们的系统的 本地行结束风格 不同的行结束格式的文件。常见的结果是,Unix 程序将 Windows 文件中存在的字符视为常规字符(通常显示为^M),而 Windows 程序将 Unix 文件的所有行合并成一行,因为没有找到表示行结束的回车换行 (或CRLF
) 字符组合。
这种对外国 EOL 标记的敏感性可能会让在不同操作系统之间共享文件的人感到沮丧。例如,考虑一个源代码文件,以及在 Windows 和 Unix 系统上编辑该文件的开发人员。如果所有开发人员始终使用保留文件行结束风格的工具,就不会出现问题。
但在实践中,许多常见工具要么无法正确读取包含外国 EOL 标记的文件,要么在保存文件时将其行结束符转换为本地风格。如果是前者,开发人员必须使用外部转换工具(例如 dos2unix 或其配套工具 unix2dos)来准备文件进行编辑。后者不需要额外的准备。但两种情况都会导致文件与原始文件在字面上每行都不一样!在提交更改之前,用户有两个选择。要么使用转换工具将修改后的文件还原为编辑之前使用的相同行结束风格。要么直接提交文件,包括新的 EOL 标记。
这些场景的结果包括浪费时间和对提交文件的无谓修改。浪费时间已经够痛苦了。但当提交更改了文件中的每一行时,这会使确定哪些行以非平凡的方式进行了更改变得复杂。那个错误到底是在哪里修复的?是在哪一行引入了语法错误?文件中的关键字将使用反映对该文件进行的最新已知提交的信息重新替换。解决此问题的方案是
native文件中的关键字将使用反映对该文件进行的最新已知提交的信息重新替换。这会导致文件包含运行 Subversion 的操作系统的本地 EOL 标记。换句话说,如果 Windows 上的用户检出包含属性。当此属性设置为有效值时,Subversion 会使用它来确定对文件执行哪些特殊处理,以便文件的行结束风格不会在每次来自不同操作系统的提交时都发生翻转。有效值为属性设置为),而 Windows 程序将 Unix 文件的所有行合并成一行,因为没有找到表示行结束的回车换行 (或的文件的工作副本,该文件将包含) 和换行 (EOL 标记。Unix 用户检出包含相同文件的工作副本,其副本中将显示
EOL 标记。) 和换行 (请注意,无论操作系统是什么,Subversion 实际上都使用规范化的
EOL 标记将文件存储在仓库中。但这对用户来说基本上是透明的。),而 Windows 程序将 Unix 文件的所有行合并成一行,因为没有找到表示行结束的回车换行 (或这会导致文件包含
EOL 标记将文件存储在仓库中。但这对用户来说基本上是透明的。) 和换行 (序列作为 EOL 标记,无论使用什么操作系统。
EOL 标记将文件存储在仓库中。但这对用户来说基本上是透明的。这意味着,默认情况下,Subversion 不会注意您的文件中使用的 行结束标记 类型。不幸的是,不同的操作系统使用不同的标记来表示文件中的文本行结束。例如,Windows 平台上的软件通常使用的行结束标记是两个 ASCII 控制字符——回车 (字符作为 EOL 标记,无论使用什么操作系统。
该字符作为 EOL 标记,无论使用什么操作系统。这种行结束风格并不常见。它曾经在较旧的 Macintosh 平台上使用(Subversion 甚至无法在这些平台上运行)。svn:externals
该属性包含有关 Subversion 如何使用一个或多个其他检出的 Subversion 工作副本填充版本化目录的说明。有关此关键字及其用法的更多信息,请参见 名为“Externals Definitions”的部分。svn:specialsvn属性是唯一一个属性包含有关 Subversion 如何使用一个或多个其他检出的 Subversion 工作副本填充版本化目录的说明。有关此关键字及其用法的更多信息,请参见 名为“Externals Definitions”的部分。属性,它不打算由用户直接设置或修改。每当“特殊”对象(例如符号链接)被安排添加时,Subversion 会自动设置此属性。仓库将
对象存储为普通文件。但是,当客户端在检出或更新期间看到此属性时,它会解释文件的内容并将该项转换回特殊类型的对象。在 Subversion 1.1 中,只有版本化的符号链接附带此属性,但在未来的 Subversion 版本中,其他特殊类型的节点也可能会使用此属性。属性包含有关 Subversion 如何使用一个或多个其他检出的 Subversion 工作副本填充版本化目录的说明。有关此关键字及其用法的更多信息,请参见 名为“Externals Definitions”的部分。注意:Windows 客户端没有符号链接,因此会忽略来自声称是符号链接的仓库的任何
属性是 Subversion 的一个强大功能,它充当本章和其他章节中讨论的许多 Subversion 功能的关键组成部分——文本差异和合并支持、关键字替换、换行符转换等。但是,要充分利用属性,必须在正确的位置设置它们。不幸的是,这很容易在例行公事中被遗忘,尤其是在没有设置属性通常不会导致明显的错误条件的情况下(至少与没有将文件添加到版本控制相比,例如)。为了帮助您将属性应用到需要它们的位置,Subversion 提供了一些简单但有用的功能。svn:mime-type每当您使用 svn add 或 svn import 命令将文件引入版本控制时,Subversion 会运行一个非常基本的启发式算法来确定该文件是否包含人类可读或不可读内容。如果做出后者的决定,Subversion 会自动将属性设置为application/octet-streamsvn:mime-type(通用“这是一组字节”MIME 类型)。当然,如果 Subversion 猜测错误,或者您希望将属性设置为更精确的值(可能是或image/pngapplication/x-shockwave-flash
),您始终可以删除或编辑该属性。Subversion 还提供了 auto-props 功能,允许您创建文件名模式到属性名称和值的映射。这些映射是在您的运行时配置区域中创建的。它们同样会影响添加和导入操作,不仅可以覆盖 Subversion 在这些操作期间做出的任何默认 MIME 类型决定,还可以设置额外的 Subversion 或自定义属性。例如,您可能创建一个映射,指示每当您添加 JPEG 文件(与模式*.jpgsvn:mime-type匹配的文件)时,Subversion 应该自动将属性设置为image/jpeg。或者,可能与*.cpp文件中的关键字将使用反映对该文件进行的最新已知提交的信息重新替换。匹配的任何文件都应该设置属性。当此属性设置为有效值时,Subversion 会使用它来确定对文件执行哪些特殊处理,以便文件的行结束风格不会在每次来自不同操作系统的提交时都发生翻转。有效值为为svn:keywords匹配的任何文件都应该设置Id和