如何在提交时忽略特定的Subversion子目录

3

在我正在工作的项目中,有人决定将二进制文件作为源代码树的一部分进行检入。这些二进制文件存放在源代码的子目录中:

project/src             # Here is the location of the source code
project/src/more_src    # Some more source code lives here
project/src/bin         # Here are the binary files

正如您所想象的那样,由于这个原因合并冲突经常发生。这非常烦人,因为我不认为任何开发者的机器都应该提交二进制文件——这应该留给构建服务器来完成。
我是subversion的命令行用户。我想忽略bin目录,以便在使用svn stsvn ci时跳过这些目录(即使有待处理的更改)。
不幸的是,由于more_src目录的存在,我无法使用-N(非递归)选项。
我该如何实现这一点?
5个回答

15

编辑:Subversion 1.6已经发布。从发布说明中可以看到:

在Subversion 1.6中,svn update命令的--set-depth参数增加了一个新值:exclude。该值告诉Subversion立即从工作副本中排除目标,并一直保持这种状态。在Subversion 1.6之前,如果一个目录不能轻易地从工作副本中删除......

以下所有内容都已过时。


您可以在适当的位置限制工作副本中文件夹的深度,使不需要的文件不会出现为已版本控制的文件。但是,您不能在现有的工作副本中减少深度。

1)像这样检出干净的工作副本(它只包含根目录下的文件和空文件夹):

svn co --depth immediates repoURL /some/wc/path

2) 现在,对于每个您不想忽略的文件夹,请使用以下命令拉取其内容:

svn update --depth infinity /some/good/path

如果要忽略的文件夹不在你的工作副本根目录中,你可以通过反复调用该命令来逐步深入到文件树中:

svn update --depth immediates /some/path/to/make/deeper

这种方法有一个不足之处。如果要忽略的文件是由您自己的操作(例如构建)出现在您的工作副本中,它们将显示为未版本化的文件。您甚至可以将它们添加到svn并导致“文件已经存在”提交错误。


编辑: 显然,您可以减少工作副本的某些部分的深度,这要简单得多:

  1. 正常的项目检出(或从现有的工作副本开始)
  2. 删除不需要的文件夹(普通的文件系统删除,而不是svn rm)。此时,该文件夹处于丢失状态,并且如果您进行正常的更新,则会返回所有其恶意内容。
  3. 使用以下命令重新引入该文件夹:

svn update --depth empty /path/where/deleted/folder/was

现在,您可以对整个项目进行svn更新,但是坏的内容不会返回。


哇,有点复杂,但是很有道理。谢谢你提供的信息。 - Frank Krueger
是的,这需要一些工作。最好的方法是将努力集中在一个脚本中,以便您可以多次调用它来创建新的工作副本。 - Wim Coenen

2
我会创建一个脚本或别名,通过一个命令直接处理子目录。
我有一个类似的情况,并且有一组像这样的别名:
alias up-all='svn up ~/includes ~/scripts ~/htdocs/intra ~/htdocs/update'

如果你使用的是Windows系统,你可以编写一些批处理脚本或其他脚本并将它们放在环境变量中,以实现相同的效果。


2
通常情况下,你只需要保留已明确发布的二进制文件,即正式版本或测试部门使用的二进制文件。因此,每次构建生成的二进制文件都不需要提交,这样做并没有意义。
因此,你的问题的真正解决方案是重新设计 SVN 存储库。构建文件所在的目录不应该在源代码控制下,并且应该使用 svn:ignore 属性忽略它们。这可以防止 SVN 注意到新构建的二进制文件。其次,你可以创建一个单独的目录来存储你想要保留的二进制文件。当然,这个目录需要在版本控制下。
现在你可以开发而不会遇到二进制文件更改的问题。当你最终需要保留这些二进制文件时,只需将这些二进制文件复制到上面创建的单独目录中,覆盖旧的文件即可。SVN 现在会注意到这些文件已经更改,然后你可以将它们提交。
过去还有一种方法,就是首先从你的源代码树创建一个 TAG。构建服务器(或你自己)然后检出这个 TAG 并从该检出的 TAG 构建二进制文件。之后,构建的二进制文件被提交到该 TAG 上。许多人认为你永远不能在 TAG 上提交,但这可能对你有效。你需要记住的唯一事情是,当你导出或检出该 TAG 时,你必须采用 HEAD 版本而不是 TAG 自己的版本(这将是 HEAD-1)。

谢谢您的想法,我完全同意。不幸的是,这是我在合同下工作的项目,我没有给他们您的演讲。我只是希望能够绕过他们的“错误”。 - Frank Krueger

1
如果它们被版本控制,那么Subversion正在发挥作用 :)
wcoenen的方法在一些工作之后也可以完成任务,另一种方法是编写一个脚本,执行svn revert /project/src/bin然后svn ci。
值得一提的是,这就是我们设置“deploy”目录并始终忽略bin和obj目录输出的原因之一。这样只有在某些发布构建中才会将二进制输出复制(并添加到svn)到deploy中。

同意,svn正在发挥它的作用。我只是不喜欢项目的设置方式,并正在寻找解决方法。 - Frank Krueger

1

需要补充的另一个重要说明(从http://svnbook.red-bean.com/nightly/en/svn.advanced.props.special.ignore.html复制):

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


你可能想要将上述技术与稀疏检出一起使用: http://svnbook.red-bean.com/en/1.5/svn.advanced.sparsedirs.html适合您用例的正确初始稀疏检出 + 在配置文件中设置适当的全局忽略可以解决问题。 - Vaibhav Gumashta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接