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

忽略未版本控制的项目

在任何给定的工作副本中,除了所有已版本控制的文件和目录外,很可能还存在其他未版本控制或不打算版本控制的文件和目录。文本编辑器会在目录中留下备份文件。软件编译器会生成中间文件,甚至最终文件,您通常不会费心版本控制。用户自己也会在他们认为合适的地方随意放置各种其他文件和目录,通常是在版本控制工作副本中。

期望 Subversion 工作副本在某种程度上不受这种混乱和杂乱的影响是荒谬的。事实上,Subversion 将其工作副本只是典型的目录,就像未版本控制的树一样,这被认为是一个特性。但是,这些不应版本控制的文件和目录可能会给 Subversion 用户带来一些困扰。例如,由于 svn addsvn import 命令默认情况下会递归地执行,并且不知道您希望在给定树中版本控制哪些文件,因此很容易意外地将您不想版本控制的内容添加到版本控制中。而且由于 svn status 默认情况下会报告工作副本中所有感兴趣的项目,包括未版本控制的文件和目录,因此在存在许多此类项目的地方,其输出可能会变得非常嘈杂。

因此,Subversion 提供了两种方法来告诉它哪些文件您希望它忽略。其中一种方法涉及使用 Subversion 的运行时配置系统(参见 名为“运行时配置区域”的部分),因此适用于所有使用该运行时配置的 Subversion 操作,通常是在特定计算机上或由特定计算机用户执行的操作。另一种方法利用 Subversion 的目录属性支持,并且与版本控制树本身绑定得更紧密,因此会影响所有拥有该树工作副本的人。这两种机制都使用文件模式(用于匹配文件名的一系列文字和特殊通配符字符)来决定要忽略哪些文件。

Subversion 运行时配置系统提供了一个选项 global-ignores,其值是一个用空格分隔的文件模式集合。Subversion 客户端会将这些模式与要添加到版本控制中的文件的名称以及 svn status 命令注意到的未版本控制的文件的名称进行比较。如果任何文件的名称与其中一个模式匹配,Subversion 将基本上像该文件根本不存在一样。这对于您几乎从不希望版本控制的那些文件非常有用,例如编辑器备份文件,例如 Emacs 的 *~.*~ 文件。

当在版本化的目录中找到时,svn:ignore 属性应包含一个换行符分隔的文件模式列表,Subversion 应使用该列表来确定同一目录中可忽略的对象。这些模式不会覆盖在 global-ignores 运行时配置选项中找到的模式,而是附加到该列表。值得再次注意的是,与 global-ignores 选项不同,在 svn:ignore 属性中找到的模式仅适用于设置该属性的目录,而不适用于其任何子目录。 svn:ignore 属性是告诉 Subversion 忽略可能存在于该目录每个用户工作副本中的文件的良好方法,例如编译器输出或(为了使用更适合本书的示例)作为将一些源 DocBook XML 文件转换为更易读的输出格式的结果而生成的 HTML、PDF 或 PostScript 文件。

[Note] 注意

Subversion 对可忽略文件模式的支持仅限于将未版本化的文件和目录添加到版本控制的一次性过程。一旦对象处于 Subversion 的控制之下,忽略模式机制就不再对其适用。换句话说,不要期望 Subversion 避免提交对版本化文件所做的更改,仅仅因为该文件的名称与忽略模式匹配 - Subversion 始终 会注意到其所有版本化对象。

全局忽略模式列表更多地取决于个人喜好,并且与用户的特定工具链更密切相关,而不是与任何特定工作副本的需求细节相关。因此,本节的其余部分将重点介绍 svn:ignore 属性及其用途。

假设您从 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 程序。 [18] 您也知道您的测试套件总是会留下这些调试日志文件。这些事实适用于此项目的全部工作副本,而不仅仅是您自己的工作副本。您知道您不想每次运行 svn status 命令时都看到这些东西,而且您确信其他人也不想看到它们。因此,您使用 svn propedit svn:ignore calc 命令在 calc 目录中添加一些忽略模式。

$ svn propget svn:ignore calc
calculator
debug_log*
$

添加此属性后,您将在 calc 目录上有一个本地属性修改。但请注意,您的 svn status 命令输出还有哪些不同:

$ svn status
 M      calc
 M      calc/button.c
?       calc/data.c

现在,所有这些杂乱无章的东西都从输出中消失了!您的 calculator 编译程序和所有这些日志文件仍然存在于您的工作副本中;Subversion 只是不再不断地提醒您它们的存在和未版本化。现在,所有无趣的噪音都从显示中消失了,您只剩下更有趣的东西——例如您可能忘记添加到版本控制中的源代码文件 data.c

当然,这并不是您工作副本状态的唯一一种简明报告。如果您确实想在状态报告中看到被忽略的文件,您可以将 --no-ignore 选项传递给 Subversion 命令。

$ svn status --no-ignore
 M      calc
 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 addsvn import 使用。这两个操作都涉及到让 Subversion 开始管理一组文件和目录。Subversion 不会强迫用户选择要开始版本控制的树中的哪些文件,而是使用忽略模式(全局和每个目录的列表)来确定哪些文件不应该作为更大递归添加或导入操作的一部分被纳入版本控制系统。同样,你可以使用 --no-ignore 选项告诉 Subversion 忽略其忽略列表,并对所有存在的文件和目录进行操作。

[Tip] 提示

即使设置了 svn:ignore,如果你在命令中使用 shell 通配符,你可能会遇到问题。shell 通配符在 Subversion 对它们进行操作之前被扩展为一个明确的目标列表,因此运行 svn SUBCOMMAND * 就如同运行 svn SUBCOMMAND file1 file2 file3 …。在 svn add 命令的情况下,这与传递 --no-ignore 选项的效果类似。因此,不要使用通配符,而是使用 svn add --force . 来批量调度未版本化的内容以进行添加。明确的目标将确保当前目录不会因为已经被版本控制而被忽略,而 --force 选项将导致 Subversion 遍历该目录,添加未版本化的文件,同时仍然遵守 svn:ignore 属性和 global-ignores 运行时配置变量。如果你不希望完全递归地查找要添加的内容,请确保还向 svn add 命令提供 --depth files 选项。



[18] 这不是构建系统的全部意义吗?

TortoiseSVN 官方中文版 1.14.7 发布