递归列出所有的svn:externals吗?

106

如何递归获取一个目录下所有 svn:externals 的列表?是否有相关的工具可以实现?

(我使用的是 Windows 操作系统,而且还有 TortoiseSVN 工具)

我有一些 svn:externals 链接到项目中不同的共享部分。当我创建分支时,通常很难找到所有的 externals 并将其更改为指向新分支内的路径。


1
这个问题也出现在https://dev59.com/RFTTa4cB1Zd3GeqPuq0V - Thiago Burgos
6个回答

168

在您的工作副本根目录下执行以下操作:

svn propget svn:externals -R

正如下面评论中所讨论的,这并不会列出外部引用。

对于TortoiseSVN用户,请注意:TortoiseSVN安装程序中有一个选项可以安装SVN命令行客户端。默认情况下,此选项未启用。


4
你似乎在使用较旧版本的SVN,因为在1.6.1版本中输出确实包含了这些信息。 - Wim Coenen
1
抱歉,我必须给它投反对票,因为a)这不会输出所有外部内容;例如,如果我们有一个外部文件夹,并且在此文件夹内部的某个地方有一个外部文件 - 这将不会显示出来b)问题标记为tortoise svn,但答案与命令行客户端相关。 - pmod
3
a) 我之前不知道这件事,但这似乎是一个SVN的bug而非我的错误。 b) TortoiseSVN 1.7安装程序包含命令行客户端! - Wim Coenen
@aWim a)将检查这是否是真正的错误或限制 - 您可以更正您的答案 b)是的,但默认情况下不会(刚刚在我的电脑上更新) - pmod
1
递归性是针对您调用命令的工作副本的文件夹结构而言的,而不是嵌套在外部的外部。因此,我认为这不是一个错误。否则,这将使操作在持续时间方面更加难以使用。 - Frank Rem
显示剩余5条评论

15

手动更改所有这些外部属性听起来很繁琐。你看过Subversion 1.5中添加的外部定义功能的新功能吗?

Subversion 1.5在缓解这些问题方面迈出了重要一步。如前所述,新的外部定义格式中使用的URL可以是相对的,并且Subversion提供了语法魔法以指定多种URL相对性。

../

    相对于设置svn:externals属性的目录的URL

^/

    相对于在其中版本化svn:externals属性的存储库的根

//

    相对于设置svn:externals属性的目录的URL方案

/

    相对于在其中版本化svn:externals属性的服务器的根URL

也许其中之一会有帮助?我想这取决于你的分支方式和存储库结构的具体情况。


10

我的TortoiseSVN解决方案:

从SVN上下文菜单中打开“分支/标记...”对话框。较低的对话框显示所有外部资源,包括嵌套的外部资源。


看起来TortoiseSVN不会递归地查找svn:externals中的svn:externals,因此这与执行svn propget svn:externals -R相同。 - paulie4

0

我使用了Wim Coenen的答案,并编写了以下脚本来创建所有修订版本的列表:

getSvnRevs() {
  cd "$1"
  wcver="$(svnversion)"
  [ -n "$wcver" ] || panic "Unable to get version for $wcdir"
  echo "$1: $wcver"
  svn propget svn:externals -R | while read a b c d e; do
    [ -n "$a" ] || continue
    if [ "$b" = "-" ]; then
      wcparent="$a"
      wcdir="$wcparent/$c"
      [ -z "$e" ] || panic "Invalid format #1"
    else
      [ -n "$wcparent" ] || panic "Invalid format #2"
      wcdir="$wcparent/$a"
      [ -z "$c" ] || panic "Invalid format #3"
    fi
    [ -d "$wcdir" ] || panic "Invalid directory: $wcdir"
    wcver="$(svnversion "$wcdir")"
    [ -n "$wcver" ] || panic "Unable to get version for $wcdir"
    echo "$1/$wcdir: $wcver"
  done
}

幸运的是,我没有嵌套的外部引用,所以我不需要测试这个,我猜它不会起作用。但如果你需要这个功能,可能只需要递归调用这个函数就可以了。此外,我从未测试过需要转义的文件名。那时它可能无法正常工作。

免责声明:我知道原来的问题是关于Windows的,而且除非你使用cygwin或类似的东西,否则shell脚本在那里不起作用。


0

我采用了Daniel Alder的答案,去掉了svnversion调用,并使其递归(注意:如果源或目标中有空格,则read a b c d e无法工作)。这是一个bash脚本,所以你需要类似Cygwin的东西或使用Windows子系统来运行Linux

getSvnExternals() {
  svnbase="$1"
  svnpath="$2"
  svn propget svn:externals -R "$svnbase/$svnpath" 2> /dev/null | while read a b c d e; do
    [ -n "$a" ] || continue
    if [ "$b" = "-" ]; then
      wcparent="$a"
      external="$c"
      wcdir=$(echo "$wcparent/$d" | sed s#^./##)
      [ -z "$e" ] || echo "WARNING: Invalid format #1. line='$a $b $c $d $e'"
    else
      [ -n "$wcparent" ] || echo "WARNING: Invalid format #2. wcparent=$wcparent"
      external="$a"
      wcdir=$(echo "$wcparent/$b" | sed s#^./##)
      [ -z "$c" ] || echo "WARNING: Invalid format #3. line='$a $b $c $d $e'"
    fi
    echo "$1/$wcdir: $external"
    ## recurse into external directory
    [ -d "$wcdir" ] && getSvnExternals "$1/$wcdir"
  done
}

0
也许,作为一种解决方法,您可以按照某种方式构建项目,使得所有外部文件都设置在同一个文件夹中,例如在Trunk下方的项目文件夹中。(这并不意味着所有外部文件夹都必须具有相同的深度。)然后,您可以右键单击项目文件夹,选择属性,然后选择Subversion选项卡,再选择属性,最后双击svn:externals。

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