【问题标题】:How to properly create an SVN tag from trunk?如何从主干正确创建 SVN 标签?
【发布时间】:2010-10-25 11:33:51
【问题描述】:

我正在Subversion 创建我的第一个项目。到目前为止我有

 branches
 tags
 trunk

我认为我需要立即使分支变得单一并重新开始。 更新分支是常态。

我一直在trunk中工作并将内容移动到标签中,如下所示。

mkdir tags/1.0
cp -rf trunk/* tags/1.0
svn add tags/1.0
svn commit -m " create a first tagged version"

我的直觉告诉我这是完全错误的,我应该使用svn copy 来维护文件之间的某种关系。我以这种方式创建的文件彼此之间没有任何关系,而且我肯定会错过 Subversion 的功能。我说的对吗?

我应该对单个文件使用 svn copy 吗?

mkdir tags/1.0
svn add tags/1.0
svn copy trunk/file1 tags/1.0
svn copy trunk/file2 tags/1.0
svn copy trunk/file3 tags/1.0
svn commit -m " create a first tagged version"

我应该在整个目录上使用 svn copy 吗?

svn copy cp -rf trunk tags/1.0
svn commit -m " create a first tagged version"

【问题讨论】:

  • 不幸的是,在这种情况下,我没有做出所有的选择...... git 真是太神奇了。

标签: svn tags


【解决方案1】:

用途:

svn copy http://svn.example.com/project/trunk \
      http://svn.example.com/project/tags/1.0 -m "Release 1.0"

速记:

cd /path/to/project
svn copy ^/trunk ^/tags/1.0 -m "Release 1.0"

【讨论】:

  • 我将此标记为答案。只是一个额外的说明。您可以获得主干的先前版本并“标记”它。命令:svn copy -r 123 "svn.example.com/project/trunk" "svn.example.com/project/tags/1.0" -m "标记,但使用旧版本 (123)。"
  • 我得到 svn: Local, non-commit operations do not take a log message or revision properties,所以我只删除了 -m 选项。
  • 仅供参考,请确保您的 url 与您的存储库匹配,包括 http 或 https。
  • 为什么第一行末尾有\?
  • @Jonny 如果没有“-m”选项,我将无法运行上述命令。我在 mac 上使用终端。
【解决方案2】:

您是正确的,将文件添加到标签文件夹是不“正确的”。

您已经正确猜到copy 是要使用的操作;它让 Subversion 可以跟踪这些文件的历史记录,并且(我假设)更有效地存储它们。

根据我的经验,最好复制整个项目(即从根签出位置中的所有文件)(“快照”)。这样,快照就可以独立存在,作为整个项目在特定时间点的状态的真实表示。

This part of "the book" 显示了该命令的典型用法。

【讨论】:

  • 文件复制不占用额外空间
【解决方案3】:

正如@victor hugo 所说,“正确”的方法是使用svn copy。 不过有一个警告。以这种方式创建的“标签”将不是真正的标签, 它将是指定修订版的精确副本,但会有所不同 修订本身。因此,如果您的构建系统以某种方式使用 svn revision (例如,将使用 'svn info' 获得的数字合并到 您构建的产品),那么您将无法构建完全相同的产品 来自标签(结果将具有标签的修订版而不是 原始代码)。

从设计上看,svn 无法创建真正合适的元标记。

【讨论】:

  • 可以使用“Last Changed Rev”:echo "{ 'svnRev': \"`svn info | awk '/Last Changed Rev:/{print $4}'`\" }" >svnver.txt`
  • 这样,(当然)不同版本号的两个分支仍然产生相同的软件版本。
  • 是的,你对 Last Changed Rev 的看法是对的,但这并不能改变 Subversion 设计中没有真正标签的事实。
  • @18446744073709551615:您可以避免使用awk,并使用--show-item选项直接从svn获取该信息:svn info --show-item last-changed-revision
  • @AlexanderAmelkin 该标签仅用于其属性以创建时间和地点的原子存储(修订版+文件夹)。您永远不需要签出工作副本的标签,您可以使用标签的单点历史来获取其真实内容。我希望我的措辞不会让你感到困惑。我主要使用照片的比喻:标签是照片,拍摄照片时的树干或树枝(部分)是您感兴趣的内容。由于照片本身包含在repo中,因此它有自己的时间和地点。
【解决方案4】:

【讨论】:

  • 我将在此基础上构建一个更大的系统,因此我需要专注于提供的核心功能。
【解决方案5】:

就用这个吧:

svn  copy  http://svn.example.com/project/trunk  
           http://svn.example.com/project/branches/release-1
           -m  "branch for release 1.0"

(当然,都在一行上。)您应该始终创建整个主干文件夹和内容的分支。当然可以对主干的子部分进行分支,但这几乎不是一个好习惯。您希望分支的行为与现在的主干完全一样,为此您必须对整个主干进行分支。

在我的博客上查看关于 SVN 使用情况的更好总结:SVN EssentialsSVN Essentials 2

【讨论】:

  • 你能详细说明如果我只从主干检查输出并且我在里面我的脚本应该是什么样子。
  • 如果你已经检出trunk文件夹,那么你需要使用repository的http地址。我已经更新了答案来表示这一点,因为推荐使用树干文件夹。
  • 这个答案与接受的答案有何不同?
【解决方案6】:

@victor hugo 和@unwind 是正确的,而 victor 的解决方案是迄今为止最简单的。但是请注意您的 SVN 项目中的外部因素。如果您引用外部库,当您标记具有外部引用的目录时,外部的修订引用(无论是标签、HEAD 还是编号)将保持不变。

可以创建一个脚本来处理这方面的标记,有关该主题的讨论,请参阅这篇 SO 文章:Tagging an SVN checkout with externals

【讨论】:

    【解决方案7】:

    标记 Subversion 存储库的另一个选项是将标记添加到 svn:log 属性,如下所示:

       echo "TAG: your_tag_text" > newlog
       svn propget $REPO --revprop -r $tagged_revision >> newlog
       svn propset $REPO --revprop -r $tagged_revision -F newlog
       rm newlog
    

    我最近开始认为这是最“正确”的标记方式。这样您就不会创建额外的修订(就像使用“svn cp”一样),并且仍然可以通过在“svn log”输出上使用 grep 轻松提取所有标签:

       svn log | awk '/----/ {
                          expect_rev=1;
                          expect_tag=0;
                      }
                      /^r[[:digit:]]+/ {
                          if(expect_rev) {
                              rev=$1;
                              expect_tag=1;
                              expect_rev=0;
                          }
                      }
                      /^TAG:/ {
                          if(expect_tag) {
                              print "Revision "rev", Tag: "$2;
                          }
                          expect_tag=0;
                      }'
    

    此外,如果需要,您可以通过这种方式无缝地删除标签。所以标签变成了完整的元信息,我喜欢。

    【讨论】:

      【解决方案8】:
      svn copy http://URL/svn/trukSource http://URL/svn/tagDestination -m "Test tag code" 
        $error[0].Exception | Select-object Data
      

      您所要做的就是更改 URL 路径。此命令将创建新目录“tagDestination”。如果发生任何错误,第二行将告知您完整的错误详细信息。 如果未创建,则创建 svn env 变量。 可以检查(Cmd:- set, Powershell:- Get-ChildItem Env:) 默认路径为“C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe”

      【讨论】:

        【解决方案9】:

        试试这个。它对我有用:

        mkdir <repos>/tags/Release1.0
        svn commit <repos>/tags/Release1.0 
        svn copy <repos>/trunk/* <repos>/tag/Release1.0
        svn commit <repos/tags/Release1.0 -m "Tagging Release1.0"
        

        【讨论】:

        • 这绝对是一条错误的路。标记(Release1.0)应该是源目录(主干)的副本,而不是任意创建的目录。如果按照您的方式进行操作,您将丢失源目录本身的历史记录,而只保留后代节点(文件和目录)的历史记录。
        猜你喜欢
        • 1970-01-01
        • 2013-09-11
        • 2012-07-03
        • 1970-01-01
        • 1970-01-01
        • 2012-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多