SVN:仅检出/导出目录结构

35
有没有一种方法可以执行SVN的检出(或导出),只获取目录结构,也就是说不包含文件?

只是好奇 - 你为什么想要这样做? - Tim
2
@Tim:看起来这是一种很好的方法,可以基于现有项目的目录结构来设置新项目的目录结构。 - onnodb
2
我再加一个原因 - 我们有一个用于许多事情(而不仅仅是源代码)的大型 SVN 结构。我想只同步我关心的目录,但是希望整个结构在本地存在。这不是一个正常的路径情况,但似乎会很有用。 - Cory Foy
你应该查看这篇文章(但如果目录深度很深,可能无法满足您的需求),http://svnbook.red-bean.com/en/1.7/svn.advanced.sparsedirs.html - dreamtale
检查一下这个线程:https://dev59.com/bm865IYBdhLWcg3wA5yc - smwikipedia
显示剩余2条评论
12个回答

13
svn ls -R {svnrepo} | grep "/$" | xargs -n 1 mkdir -p

导出而不是检出。

[已更新]

使用检出:

env REPO={repo} sh -c 'svn ls -R $REPO | grep "/\$" | xargs -n 1 svn co --depth=empty $REPO'

对于过大的数据,这种方法速度会比较慢。


请问是否可以使用实际的 SVN 检出来完成这个操作?我想要一个包含所有受版本控制的目录的副本(即:每个目录都有 .svn 子文件夹,就像我执行“svn co --non-recursive”命令一样)。 - Cloud
如果您的文件夹名称中包含空格,请使用以下命令:svn ls -R {svnrepo} | grep "/$" | xargs -I {} mkdir -p "{}" - architectonic
这段程序相关的内容翻译成中文如下:这个方法对我非常有用,它让我以一个空的工作副本开始工作:https://resbook.wordpress.com/2011/01/06/check-out-directory-in-svn-without-checking-out-the-content-of-directory/。 - i_a
2
一个基于 @architectonic 评论的变体,也能处理带引号等特殊符号的文件名:svn ls -R {svnrepo} | grep "/$" | tr '\n' '\0' | xargs -0 -n 1 mkdir -p - Robert Fleming

9

您可以使用--non-recursive参数在checkout命令中指定,这可能有助于您获取所需内容。


3
我不认为这会有帮助。--non-recursive就是按字面意思:它不会递归遍历整个树形结构。因此,这只会给你顶层对象,这并不是OP想要的,除非他们有一个扁平的目录结构(像灌木丛而不是树)。 - SQB

5

在Subversion的contrib工具中有一个Python脚本,它可以创建带有空文件的目录结构。 只要稍微了解一点Python知识,就可以轻松地跳过创建文件的步骤。


4

SVN本身不能做到这一点,但如果您只想导出目录结构,请尝试svn ls -R --xml,以获取目录结构的XML列表,然后手动重新创建它。


4

检查目录结构的用途是部分解决无法排除一个或多个目录进行检出的问题。假设仅检出目录树的成本与检出完整源代码相比可以忽略不计。通过检出版本化的目录结构,我可以使用Subversion的更新和{{link1:稀疏目录}}来选择性地选择哪些目录树应该有文件。


3

这个完美运行

svn ls | xargs svn up -N

如果您想完全检查其中几个目录,请进入这些目录并使用以下命令:

svn ls | xargs svn up

2

我想补充一点,如果你需要在服务器端执行此操作(即不首先检出存储库),则相当于 svn ls 的是 svnlook tree --full-paths

我不得不创建一个50GB存储库的文件夹结构的副本,并使用我在这里找到的提示来完成此操作,而无需创建整个工作副本。

我的代码如下:

svnlook tree /path/to/repo --full-paths | grep "/$" | grep -v "^/$" | xargs -I {} mkdir -p "{}"

由于输出包含单个 /(即文件系统根文件夹),因此我不想处理它,所以使用了 grep -v "^/$"


1
在Windows上,使用TortoiseSVN可以进行Checkout->仅此项的检出深度。这样,您就可以获取单个文件夹/文件。您可以使用repobrowser以这种方式重建您的结构。如果您的目录结构不太复杂,这可能有点麻烦,但是可行的。我更喜欢这种方法,而不是通过缓慢的网络检出数千个小文件(几个GB)。

1
或者在同一个屏幕上,您可以将“Checkout depth”保留为“完全递归”,并在组合框下方的右下角按钮“选择项目”中取消选中您不想获取的文件。 - Canella

1

您可以使用此脚本,它将列出svn repos并在目录中创建结构。

用法: perl checkout-structure.pl repos destdir

repos不能是您的repos根目录,它也可以指定一个目录。

无法创建包含重音字符(àéîùç...)的目录,但对于包含空格的目录可以正常工作。对于那些有时间解决这个问题的人来说,我认为这是一个编码问题。

checkout-structure.pl:

#!perl

my @dirs;
my $repos = shift;
my $dest = shift;

@dirs = grep { /\/$/ && /^[^\.]/ } `svn list -R $repos`;

foreach(@dirs) {
    s/\/$//;
    chomp;
    mkdir("$dest/$_") or warn $!." trying to create $dest/$_";
}

1

我的DotNet(LINQ)实现方法如下:

首先,运行svn list命令。并将输出推送到一个.xml文件中。

"svn.exe" list "https://myserver.com:8443/svn/DotNet/src/v40Base/v40/" --recursive --username %USERNAME% --xml >>myfile.xml

然后对 .xml 文件运行一些 LINQ 代码。

    private static void FindSVNDirectories()
    {

        string fileName = @"C:\temp\myfile.xml";

        XDocument xDoc = XDocument.Load(fileName);

        //XNamespace ns = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");
        string ns = string.Empty;

        //List of directories
        var list1 = from list in xDoc.Descendants(ns + "list")
                    from item in list.Elements(ns + "entry")
                    where item.Attribute("kind").Value=="dir"
                    select new
                       {
                           mykind = item.Attribute("kind").Value,
                           myname = (item.Element(ns + "name").Value)
                       };

        StringBuilder sb = new StringBuilder();
        foreach (var v in list1)
        {
            sb.Append(v.ToString() + System.Environment.NewLine );
        }

        Console.WriteLine(sb.ToString());


    }

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