我在我公司维护构建系统,目前正在使用CVS。此构建系统用于多个项目和多个CVS存储库。
每当我们有一个发布里程碑时,我们都会创建一个标记。在CVS中,这很简单:
$ cvs tag TAG_NAME
无论CVS模块或存储库如何,该命令都可以工作,只要它在CVS工作目录中执行即可。
为了在subversion中执行相同的操作,看起来我首先必须解析svn info
的输出以获取存储库根目录。然后我可以用:
svn cp . $REPO_ROOT/tags/TAG_NAME -m"Created tag TAG_NAME"
这当然假设svn存储库具有推荐的“trunk,tags,branches”目录结构。所以为了安全起见,我可能需要首先验证这一点。
将修订号映射到符号名称似乎需要做很多工作。还有更好的方法吗?
答案 0 :(得分:5)
我几乎完全从命令行使用svn而且我很快就厌倦了输入怪物URL。我终于写了一个脚本svnurl
,我在shell中使用它。它的运作假设“项目”具有以下形式:
.../PROJECTNAME/trunk
tags
branches
让我们假设你在PROJECTNAME / branches / foo的工作副本中的某个地方:
svnurl -tl # gives a list of tags for the current project
svnurl -tlu # the same as full urls
svnurl -t 1.1 # the url for the tag 1.1 of the current project
# analagous functions for branches
svnurl -ru # the url of the "root" of the current working copy
# eg svn://.../PROJECTNAME/branches/foo
svnurl -T # the url of the trunk of the current project
svnurl -pn # the name of the current project, `PROJECTNAME`
# ...
用法看起来像这样:
$ svn cp $(svnurl -T) $(svnurl -t 1.1.1) # tag trunk as 1.1.1
代码并不漂亮,但它为我节省了很多次击键,并且以我没想到的方式有用。如果你有兴趣,我愿意分享。
答案 1 :(得分:5)
您错过了Subversion的核心原则:修订号是标记。当您使用svn cp“标记”它时,您只是使用更长的名称制作该特定修订的副本。与CVS标签不同,您(或其他开发人员)可以继续在该“标签”上进行持续开发。它不是像CVS标签那样的静态实体(嗯,公平地说,你可以在单个CVS文件上移动一个有效“改变”它的标签。)
大多数svn用户以CVS呈现标签的方式处理标签。并且(至少在Apache下)您可以将DAV服务器配置为不允许在任何标记目录下进行写入/签入。我没有尝试过,它可能会阻止您使用http URL创建标记(您必须使用托管计算机上的shell的文件路径)。但是出于所有实际目的,您的发布过程应该对特定的修订号更感兴趣,而不是某些任意文本字符串。后者可在释放后改变;前者应该[*]总是让你在每次检查时都能访问完全相同的文件集。
[*]总有一种方法可以在幕后摆弄文件,事实上......当我需要修复评论等时,我曾经用vi手工编辑RCS和CVS文件。但是没有一些严重的svn-cleverness,给定的修订版号应该非常稳定。
答案 2 :(得分:5)
以下是我实施此操作的方式,万一有人好奇:
<!-- First, we need to get the svn repository root URL by parsing
the output of 'svn info'. -->
<exec executable="svn" failonerror="yes">
<arg line="info"/>
<redirector outputproperty="svninfo.out" errorproperty="svninfo.err">
<outputfilterchain>
<linecontains>
<contains value="Repository Root: "/>
</linecontains>
<tokenfilter>
<replacestring from="Repository Root: " to=""/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo level="verbose" message="Root from svn info: ${svninfo.out}"/>
<!-- Set the svn.root property from the svn info output, and append
the module prefix if it exists. The module prefix allows multiple
projects to use the same repository root. -->
<condition property="svn.root" value="${svninfo.out}/${svn.module.prefix}">
<isset property="svn.module.prefix"/>
</condition>
<!-- Note that the next line will have no effect if the property was
set in the condition above, since ant properties are immutable. The
effect is an "else", if the condition above is NOT true. -->
<property name="svn.root" value="${svninfo.out}"/>
<echo level="verbose" message="Root: ${svn.root}"/>
<!-- Verify the tags directory exists. -->
<exec executable="svn"
failonerror="no"
outputproperty="null"
errorproperty="svn.ls.error">
<arg line="ls ${svn.root}/tags"/>
</exec>
<fail>
Cannot find 'tags' subdirectory.
${svn.ls.error}
The subversion repository is expected to have 'trunk', 'branches', and 'tags'
subdirectories. The tag '${tag}' will need to be manually created.
<condition>
<not>
<equals arg1="${svn.ls.error}" arg2="" trim="yes"/>
</not>
</condition>
</fail>
<!-- Finally, do the actual tag (copy in subversion). -->
<exec executable="svn" failonerror="yes">
<arg line="cp . ${svn.root}/tags/${tag} -m 'Created tag ${tag}'"/>
</exec>
我还想指出,我知道CVS和subversion之间在标记方面的区别,并且对于所有实际目的,subversion修订版等同于标记。不幸的是,这并不是真正相关的;我的用户想要一个由模块名称和(不同的)版本号组成的符号名称。
答案 3 :(得分:2)
与CVS不同,标签不仅仅是颠覆中的符号名称,这就是重点。我们创建一个标签,您实际上正在创建一个分支。如果您还没有:http://svnbook.red-bean.com/
,我建议您阅读此内容