SVN:您能仅从本地检出中删除目录(而不是从存储库中删除)吗?

53
假设你有一个目录受到Subversion控制,包含一些文件和大量的子目录,如下所示:
file1.txt
file2.txt
file3.txt
dir1/
dir2/
dir3/
dir4/
:
dirXX/

现在您需要文件和一些目录,但不是全部。这可以通过SVN完成。只需使检出非递归即可:

svn checkout -N <URL>

这只检查第一个目录和其中的文件。不包括子目录。即使您进入检出目录并运行 "svn up",它也只会更新先前检出的文件,而不会添加目录。现在,您可以通过显式更新所需的目录来有选择性地添加这些目录。例如,如果您只需要 dir2 和 dir4,则可以进入检出目录并执行以下操作:

svn up dir2
svn up dir4

如果您将来运行通用的“svn up”,它只会更新文件和这两个目录,不会添加任何其他目录。
现在问题来了:如果我决定在以后的任何时候不再需要dir2怎么办?我该如何摆脱它?似乎没有其他方法可以做到这一点,除非删除整个checkout并从头开始。
当您只删除dir2时,下一个“svn up”将把它带回来,因为“svn status”当然显示它现在已经丢失(名称前面有“!”)。运行“svn remove”当然会将其删除,但在下一次提交时,它也会从存储库中删除,这是不允许的。
即使是SVN 1.5的新稀疏目录(“浅层checkout”)功能,在这里也没有用:
引用:
Subversion 1.5实现的浅层检出很好,但不支持一些有趣的行为。首先,您无法取消工作副本项的望远镜效果。在无限深度的工作副本中运行svn update --set-depth empty将不会放弃除最顶层目录之外的所有内容 - 它只会出错。
- http://svnbook.red-bean.com/en/1.5/svn.advanced.sparsedirs.html 这在SVN上完全不可能吗?有人想出了一个聪明的解决方法吗?

只需创建结帐目录(不使用SVN),然后直接从存储库检出各个子目录作为此目录的子目录,即可用于目录:现在每个目录都是自己的结帐,可以更新,并且一旦不再需要,您可以将其删除。但是,那么我如何获取文件(例如file1.txt)? SVN不允许检出单个文件,您只能检出整个目录。


我认为这与以下两个问题相同:https://dev59.com/H3RA5IYBdhLWcg3wsgFP,https://dev59.com/K3RB5IYBdhLWcg3wZmhz - ire_and_curses
1
@ire_and_curses:首先,你为什么不把这个写成一个答案呢?其次:这两个问题都是关于防止某些东西被提交的。这与我的问题完全无关。即使我在目录上执行svn delete并防止其被提交,该目录也不会消失。你有没有读过我的问题还是只看了标题? - Mecki
@Mecki:我确实看了你的问题,尽管我承认是匆忙地看了。我认为你是在问如何删除本地副本中的版本控制目录,而不影响存储库版本,并且在下次更新时不会再次获取该目录。虽然我没有尝试过,但似乎将其他所有内容都作为更改列表的成员将完全做到这一点。我没有将其写成答案,因为它已经存在于其他两个问题中(我认为它们是相同的)-如果我是正确的,那么我只是为别人的工作获得声望。如果这对你没有用,很抱歉。 - ire_and_curses
1
@ire_and_curses:如果你不写一个真正的答案,你就不能得到赞和我也不能直接评论你所写的内容。即使问题已经在其他地方得到了回答,也要写一个真正的答案。如果我的问题没有及时被关闭为重复,我可以接受你的答案作为“答案”,即使它只是引导我去别处。不公平吗?我认为不是。毕竟,仅通过给出链接来回答问题也会让你获得他人工作的声誉。 - Mecki
5个回答

65

我试图做的事情在Subversion 1.4或Subversion 1.5中无法完成,没有任何解决办法存在,就是这样。

但是,在Subversion 1.6中可以实现。

与SVN 1.5不同,SVN 1.6可以减少目录深度

svn up --set-depth exclude dir2

以下是解决方案,它将dir2的深度设置为零,并且它会立即从检出中消失,而且除非您明确地再次将此目录的深度设置为一个值(或者只是在没有深度选项的情况下对其进行更新,因为不给定任何深度始终意味着无限制,除非您使用非递归方式,这意味着“文件”)。

提示:
实际上,SVN 1.6不能像增加深度一样减少深度。可以从任何级别增加到任何更高级别。只能将其减少到“排除”(所有级别中最低的级别)。如果要从“无限制”(最高)减少到“文件”(在中间某个位置),则必须首先将其减少到“排除”(导致目录消失),然后再将其增加回“文件”。这有点儿取巧,但它可以正常工作。


2
可以通过提供以空格分隔的多个值来排除多个目录。例如:svn up --set-depth exclude dir1 dir2 dir3 - Ritesh
2
在我使用rm删除目录后,这个方法对我没有起作用。我不得不先恢复它,然后再运行这个命令,但之后它是成功的。 - Nickolai

41

对于后来遇到此问题并使用 TortoiseSVN 的任何人,以下是如何执行相同操作的方法...

  1. 右键单击您不再需要检出的文件夹(这是要排除的文件夹)
  2. 从上下文菜单中选择“TortoiseSVN > 更新到修订版本...”
  3. 在弹出的窗口中,将“更新深度”下拉框设置为“排除”
  4. 单击“确定”。 SVN现在将自动从您的驱动器中删除该目录。

(注意:此操作是在TortoiseSVN 1.7.5版本进行的,其他版本可能会有所不同。)


13

更新:我正在运行 SVN 1.6.11 版本,我能够使用 svn up --set-depth empty dir 命令来取消嵌套目录,而无需使用 exclude 命令。


2

使用svn 1.6,--set-depth是解决方法。

在svn < 1.6中,您可以通过滥用svn switch来获得稀疏检出:在您的存储库中创建一个空目录,并将您现在不需要的子目录switch到该目录,而不是它们的“真实”URL。


1
你可以尝试一下这个与本地仓库和svn相关的技巧外部声明

不过我自己还没有尝试过。


这听起来非常有趣!第一个回答已经是一个非常好的答案(点赞)。不确定这是否是最佳解决方案,以及它是否真的能解决我的问题,但我应该尝试一下这个解决方案。如果这有效果并且没有更简单的解决方案,我将接受这个答案。即使它不能解决我的问题,它可能会解决其他SVN问题(因此这种知识在任何情况下都很有用)。 - Mecki
抱歉,这并不能真正解决我的问题。我可以创建一个本地仓库,然后只链接其中的一些子目录,这样只有它们才会出现...而且我可能可以取消链接它们(删除外部声明),它们就会消失...但是我没有办法获取主目录中的fileX.txt文件,因为您不能链接单个文件,只能链接目录,链接此目录将链接其所有子目录和文件 :( - Mecki

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