如何访问当前的Subversion内部版本号?

时间:2020-03-06 14:29:58  来源:igfitidea点击:

如何在Subversion中自动导入最新的版本号/修订号?

这样做的目的是使该数字在网页页脚上可见。

解决方案

好吧,我们可以运行'svn info'来确定当前的修订号,并且可以很容易地使用正则表达式来提取该修订号,例如" Revision:([0-9] +)"。

svn info <Repository-URL>

或者

svn info --xml <Repository-URL>

然后看一下结果。对于xml,请解析/ info / entry / @ revision以获取存储库的修订版(在此示例中为151),或者解析/ info / entry / commit / @ revision以获取针对该路径的最后一次提交的修订版(133,与标签):

<?xml version="1.0"?>
<info>
<entry
   kind="dir"
   path="cmdtools"
   revision="151">
<url>http://myserver/svn/stumde/cmdtools</url>
<repository>
<root>http://myserver/svn/stumde</root>
<uuid>a148ce7d-da11-c240-b47f-6810ff02934c</uuid>
</repository>
<commit
   revision="133">
<author>mstum</author>
<date>2008-07-12T17:09:08.315246Z</date>
</commit>
</entry>
</info>

我为自己编写了一个工具(cmdnetsvnrev,包括源代码),该工具替代了AssemblyInfo.cs文件中的修订版。尽管它仅限于此目的,但通常是svn info,然后进行处理。

如果我们有乌龟SVN,则可以使用SubWCRev.exe

创建一个名为:

RevisionInfo.tmpl

SvnRevision = $WCREV$;

然后执行以下命令:

SubWCRev.exe . RevisionInfo.tmpl RevisionInfo.txt

它将使用以下版本号创建文件ReivisonInfo.txt:

SvnRevision = 5000;

但是,除了使用.txt之外,我们还可以使用所需的任何源文件,并可以访问源代码中的版本号。

将svn:keywords添加到源文件的SVN属性中:

svn:keywords Revision

然后在源文件中包括:

private const string REVISION = "$Revision$";

在下一次提交到" $ Revision:4455 $"`时,修订将使用修订号进行更新。我们可以解析此字符串以仅提取修订号。

如果我们在GNU / Linux下运行,请cd到工作副本的目录并运行:

svn -u status | grep Status\ against\ revision: | awk '{print }'

根据我的经验,重命名目录后,svn信息无法提供可靠的数字。

我们不会说我们正在使用哪种编程语言/框架。这是使用PySVN在Python中进行操作的方法

import pysvn
repo = REPOSITORY_LOCATION
rev = pysvn.Revision( pysvn.opt_revision_kind.head )
client = pysvn.Client()
info = client.info2(repo,revision=rev,recurse=False)
revno = info[0][1].rev.number # revision number as an integer

我们需要Subversion info子命令,如下所示:

$ svn info .
Path: .
URL: http://trac-hacks.org/svn/tracdeveloperplugin/trunk
Repository Root: http://trac-hacks.org/svn
Repository UUID: 7322e99d-02ea-0310-aa39-e9a107903beb
Revision: 4190
Node Kind: directory
Schedule: normal
Last Changed Author: coderanger
Last Changed Rev: 3397
Last Changed Date: 2008-03-19 00:49:02 -0400 (Wed, 19 Mar 2008)

在这种情况下,有两个修订版本号:4190和3397. 4190是存储库的最后修订版本号,并且3397是从中检出此工作空间的子树的最后更改的修订版本。我们可以指定工作空间的路径,也可以指定存储库的URL。

在Windows下提取该碎片的代码如下所示:

Process process = new Process();
process.StartInfo.FileName = @"svn.exe";
process.StartInfo.Arguments = String.Format(@"info {0}", path);
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();

// Parse the svn info output for something like "Last Changed Rev: 1234"
using (StreamReader output = process.StandardOutput)
{
    Regex LCR = new Regex(@"Last Changed Rev: (\d+)");

    string line;
    while ((line = output.ReadLine()) != null)
    {
        Match match = LCR.Match(line);
        if (match.Success)
        {
            revision = match.Groups[1].Value;
        }
    }
}

(就我而言,我们使用Subversion修订版作为程序集版本号的一部分。)

使用cand SharpSvn(来自http://sharpsvn.net),代码为:

//using SharpSvn;
long revision = -1;
using(SvnClient client = new SvnClient())
{
  client.Info(path,
    delegate(object sender, SvnInfoEventArgs e)
    {
       revision = e.Revision;
    });
}

让构建过程调用svnversion命令,并将其输出嵌入到生成的{source | binaries}中。这不仅会给出当前的修订版本(如此处的许多其他示例所示),而且其输出字符串还将告诉我们构建是在混合树中完成还是在与所讨论的修订版本号不完全匹配的树中进行(即一棵有局部变化的树)。

使用标准树:

$ svnversion
3846

使用修改后的树:

$ echo 'foo' >> project-ext.dtd
$ svnversion                   
3846M

使用混合修订的修改树:

$ (cd doc; svn up >/dev/null 2>/dev/null)
$ svnversion
3846:4182M

在我的最新项目中,我通过使用多个工具,SVN,NAnt和自定义NAnt任务解决了此问题。

  • 使用NAnt执行svn info --xml。/ svnInfo.xml
  • 使用NAnt通过<xmlpeek>从xml文件中获取修订号。
  • 在编译项目之前,请使用自定义的NAnt任务使用最新的版本号(例如,major.minor.maintenance,修订版)更新AssemblyInfo.cs文件中的AssemblyVersion属性。

我的构建脚本中与版本相关的部分如下所示:

<!-- Retrieve the current revision number for the working directory -->
<exec program="svn" commandline='info --xml' output="./svnInfo.xml" failonerror="false"/>
<xmlpeek file="./svnInfo.xml" xpath="info/entry/@revision" property="build.version.revision" if="${file::exists('./svnInfo.xml')}"/>

<!-- Custom NAnt task to replace strings matching a pattern with a specific value -->
<replace file="${filename}" 
         pattern="AssemblyVersion(?:Attribute)?\(\s*?\&quot;(?&lt;version&gt;(?&lt;major&gt;[0-9]+)\.(?&lt;minor&gt;[0-9]+)\.(?&lt;build&gt;[0-9]+)\.(?&lt;revision&gt;[0-9]+))\&quot;\s*?\)" 
         value="AssemblyVersion(${build.version})"
         outfile="${filename}"/>

正则表达式的代码为:http://code.mattgriffith.net/UpdateVersion/。但是,我发现UpdateVersion不能满足我的需要,因为我的构建中的别针功能已损坏。因此,自定义NAnt任务。

如果有人对代码感兴趣,请告诉我自定义的NAntreplace任务。由于这是与工作相关的项目,因此我需要与管理层联系,以查看是否可以根据友好(免费)许可发布它。

svnversion命令是执行此操作的正确方法。它会输出整个工作副本所在的修订版本号,或者输出混合工作副本的一系列修订版本(例如,某些目录是最新的,而某些目录不是最新的)。它还将指示工作副本是否具有本地修改。例如,在一个不干净的工作目录中:

$ svnversion
662:738M

$ Revision $关键字不会执行我们想要的操作:仅当包含文件时才会更改。 Subversion本书提供了更多细节。 " svn info"命令也不会执行我们想要的操作,因为它仅告诉我们当前目录的状态,而忽略任何子目录的状态。在与上一个示例相同的工作树中,我有一些子目录,这些子目录比我所在的目录新,但" svn info"没有注意到:

$ svn info
... snip ...
Revision: 662

将svnversion合并到构建过程中很容易,因此每个构建都以某种可在运行时访问的形式获取修订号。例如,对于一个Java项目,我让我们的makefile将svnversion输出转储到.properties文件中。

在Rails中,我在我的environment.rb中使用此代码段,这使我可以在整个应用程序中使用该常量(例如在应用程序布局的页脚中)。

SVN_VERSION  = IO.popen("svn info").readlines[4].strip.split[1]

这是一个提示,说明如何使用Netbeans的功能来
创建将生成scm-version.txt的自定义ant任务:

打开build.xml文件,然后在后面添加以下代码
`<import file =" nbproject / build-impl.xml" />

<!-- STORE SUBVERSION BUILD STRING -->
<target name="-pre-compile">
  <exec executable="svnversion"
    output="${src.dir}/YOUR/PACKAGE/NAME/scm-version.txt"/>
</target>

现在,Netbeans使用Subversion版本字符串
每次进行清理/构建时,都访问scm-version.txt。

我们可以通过在运行时读取文件来执行以下操作:

getClass().getResourceAsStream("scm-version.txt"); // ...

不要忘记将文件scm-version.txt标记为svn:ignore。

我使用MSBuild社区任务项目,该项目具有检索SVN版本号并将其添加到AssemblyInfo.vb的工具。然后,我们可以使用反射来检索此字符串以在UI中显示它。

这是带有说明的完整博客文章。

如果使用的是svnant,则可以使用wcVersion,它会复制svnveresion并返回可消化的值。看:
http://subclipse.tigris.org/svnant/svn.html#wcVersion

我为CodePlex上的Build Version Increment项目创建了SVN版本插件。该SVN插件将从工作副本中获取最新的变更修订版本号,并允许我们在版本号中使用该版本号,该版本号将完全完成我们要执行的操作。 Build Version Increment非常灵活,可以让我们以多种方式设置版本控制的完成方式。

BVI仅适用于Visual Studio,但是由于我们使用的是Asp.Net,所以这不会成为问题。它不需要编写任何代码或者编辑xml,所以是的!