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

你怎么能自动导入最新的版本/修订号在颠覆?

目标是让这个数字在你的网页页脚上像SO一样可见。

svn info <Repository-URL> 

要么

 svn info --xml <Repository-URL> 

然后看看结果。 对于修订版本库(本例中为151)或/ info / entry / commit / @ revision的xml,parse / info / entry / @ revision,修改上一次提交的此path(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文件中的版本。 尽pipe如此,但是一般情况下svn的信息和处理都是要走的路。

让您的构build过程调用svnversion命令,并将其输出embedded到生成的{源|二进制文件}中。 这不仅会给出当前的修订版(这里还有很多其他的例子),但是它的输出string也会告诉你在一个混合树或者一棵树中是否完成了一个构build, 。有本地变化的树)。

用标准树:

 $ svnversion 3846 

用修改过的树:

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

用混合修订版本修改树:

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

svnversion命令是执行此操作的正确方法。 它会输出您的整个工作副本所在的修订版本号,或者如果您的工作副本混在一起(例如,某些目录是最新的,而有些不是),则会进行一系列修订。 这也将表明工作副本是否有本地修改。 例如,在一个相当不干净的工作目录中:

 $ svnversion 662:738M 

$ Revision $关键字没有做你想做的事情:只有当包含文件的时候它才会改变。 Subversion的书提供了更多的细节 。 “svn info”命令也没有做你想做的事情,因为它只告诉你当前目录的状态,忽略任何子目录的状态。 在与前面的例子相同的工作树中,我有一些比我所在的目录更新的子目录,但是“svn info”没有注意到:

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

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

将svn:关键字添加到源文件的SVN属性中:

 svn:keywords Revision 

然后在源文件中包含:

 private const string REVISION = "$Revision$"; 

修订版本将在下次提交(例如) "$Revision: 4455$"更新为修订版本号。 你可以parsing这个string来提取修订号。

如果你有乌龟SVN你可以使用SubWCRev.exe

创build一个名为:

RevisionInfo.tmpl

 SvnRevision = $WCREV$; 

然后执行这个命令:

 SubWCRev.exe . RevisionInfo.tmpl RevisionInfo.txt 

它将创build一个文件ReivisonInfo.txt与您的修订号码如下:

 SvnRevision = 5000; 

但是,不要使用.txt文件,你可以使用任何你想要的源文件,并且可以访问源代码中的reivsion编号。

你不会说你正在使用什么编程语言/框架。 以下是如何使用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 

使用c#和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; }); } 

在我最近的项目中,我使用了几个工具,SVN,NAnt和一个自定义NAnt任务来解决这个问题。

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

我的构build脚本的版本相关部分如下所示:

 <!-- 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}"/> 

正则expression式的功劳如下: http : //code.mattgriffith.net/UpdateVersion/ 。 但是,我发现UpdateVersion没有满足我的需求,因为在我的构build中引脚function被破坏了。 因此,自定义NAnt任务。

如果任何人有兴趣的代码,自定义NAnt replace任务让我知道。 由于这是一个与工作有关的项目,我将需要与pipe理层核实,看看我们是否可以在友好(免费)许可下发布。

这是一个提示,你可能会使用Netbeans的function
创build将生成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每次进行清理/构build时都会将Subversion版本string转换为scm-version.txt

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

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

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

在Rails中,我在我的environment.rb中使用这个片段,它给了我一个可以在整个应用程序中使用的常量(就像在应用程序布局的页脚中一样)。

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

那么,你可以运行'svn info'来确定当前的修订版本号,你可以用一个正则expression式很容易地提取它,比如“Revision:([0-9] +)”。

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

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

根据我的经验,在重命名目录后,svn info并不能提供可靠的数字。

你需要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是此工作空间检出的子树的最后一次更改的版本号。 您可以指定工作区的path或存储库的URL。

AC#片段在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修订版作为程序集版本号的一部分。)

我使用MSBuild社区任务项目,它有一个工具来检索SVN修订版本号并将其添加到您的AssemblyInfo.vb。 然后,您可以使用reflection来检索此string以在您的用户界面中显示它。

这里有一个完整的博客文章与指示 。

如果你使用svnant,你可以使用wcVersion,它重复svnveresion并返回易消化的值。 请参阅: http : //subclipse.tigris.org/svnant/svn.html#wcVersion

我为CodePlex上的Build Version Increment项目创build了一个SVN版本插件 。 这个SVN插件将从你的工作副本中提取最新的更改版本号,并允许你在你的版本号中使用它,这应该完成你想要做的事情。 构build版本增量非常灵活,可以让您设置版本的完成方式。

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