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

Posted

技术标签:

【中文标题】如何访问当前的 Subversion 内部版本号?【英文标题】:How to access the current Subversion build number? 【发布时间】:2010-09-11 17:31:40 【问题描述】:

如何在 subversion 中自动导入最新的构建/修订号?

我们的目标是像 SO 那样在您的网页页脚上显示该数字。

【问题讨论】:

【参考方案1】:

好吧,您可以运行“svn info”来确定当前的修订号,并且您可以使用正则表达式轻松提取它,例如“修订:([0-9]+)”。

【讨论】:

svn info | sed -n 's/^Revision: //p'【参考方案2】:
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 然后处理是要走的路。

【讨论】:

【参考方案3】:

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

创建一个名为:

RevisionInfo.tmpl

SvnRevision = $WCREV$;

然后执行这个命令:

SubWCRev.exe . RevisionInfo.tmpl RevisionInfo.txt

它将使用您的修订号创建一个文件 ReivisonInfo.txt,如下所示:

SvnRevision = 5000;

但您可以使用任何您想要的源文件,而不是使用 .txt,并且可以访问源代码中的版本号。

【讨论】:

【参考方案4】:

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

svn:keywords Revision

然后在源文件中包含:

private const string REVISION = "$Revision$";

在下一次提交到(例如)"$Revision: 4455$" 时,将使用修订号更新修订。您可以解析此字符串以仅提取修订号。

【讨论】:

关于这个的问题:我发现 $Revision$ 只有在特定文件更改时才会更新,否则它保持不变。有没有办法在每次签入/签出时强制更新 $Revision$,无论文件是否在上次提交中被修改? 不,您必须更改文件并提交才能使其正常工作。我一直只是在包含版本号或发行说明的文件中包含 REVISION const,无论如何,这些版本通常在发布之前更新。 如果文件是 .js 文件,你会怎么做?【参考方案5】:

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

svn -u 状态 | grep 状态\反对\修订:| awk 'print $4'

根据我的经验,重命名目录后 svn info 不会给出可靠的数字。

【讨论】:

和往常一样,grep foo | awk ' bar ' 可以最有用地重构为 awk '/foo/ bar ' -- svn -u status | awk '/Status against revision:/ print $4 '【参考方案6】:

你没有说你正在使用什么编程语言/框架。下面是如何在 Python 中使用PySVN

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

【讨论】:

【参考方案7】:

你想要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 下提取它的 C# 片段如下所示:

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 版本作为程序集版本号的一部分。)

【讨论】:

【参考方案8】:

使用 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;
    );

【讨论】:

【参考方案9】:

让您的构建过程调用svnversion 命令,并将其输出嵌入到生成的source|binaries 中。这不仅会给出当前版本(就像这里的许多其他示例一样),而且它的输出字符串还将告诉构建是在混合树中完成还是在与所讨论的版本号不完全匹配的树中完成(即. 一棵具有局部变化的树)。

使用标准树:

$ svnversion
3846

使用修改后的树:

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

使用混合修订、修改后的树:

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

【讨论】:

知道如何让它同时列出任何外部组件的版本吗? @ShoeLace - 遗憾的是,没有使用 svnversion —— 但是一点点 grep 和 awk 对 svn 状态的工作——verbose 会得到你想要的。 @ShoeLace, ...btw,更新一下——今天,我将使用svn status --verbose --xml,与 XMLStarlet 或 XSLT 模板后处理。【参考方案10】:

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

    使用 NAnt 执行svn info --xml ./svnInfo.xml 使用 NAnt 从带有 &lt;xmlpeek&gt; 的 xml 文件中提取修订号 在编译项目之前,使用自定义 NAnt 任务将 AssemblyInfo.cs 文件中的 AssemblyVersion 属性更新为具有最新版本号的最新版本(例如,major.minor.maintenance、修订版)。

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

<!-- 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 不能满足我的需求,因为我的构建中的 pin 功能被破坏了。因此自定义 NAnt 任务。

如果有人对代码感兴趣,请告诉我自定义 NAnt replace 任务。由于这是一个与工作相关的项目,我需要与管理层核实,看看我们是否可以在友好(免费)许可下发布它。

【讨论】:

【参考方案11】:

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

$ svnversion
662:738M

$Revision$ 关键字不会做你想做的事:它只会在包含文件的时候改变。 Subversion 书给出了more detail。 “svn info”命令也不会做你想做的事,因为它只告诉你当前目录的状态,而忽略任何子目录的状态。在与上一个示例相同的工作树中,我有一些子目录比我所在的目录新,但“svn info”没有注意到:

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

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

【讨论】:

请接受我对现在被推翻的反对票的道歉。当时,我认为这近乎抄袭——但它确实添加了新内容(解释$Revision$ 的限制,建议使用makefile 等),而无需逐字复制任何文本,因此它作为自己的答案是完全合法的。 【参考方案12】:

在 Rails 中,我在 environment.rb 中使用了这个 sn-p,它为我提供了一个可以在整个应用程序中使用的常量(例如在应用程序布局的页脚中)。

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

【讨论】:

哇,就是这么简单。谢谢!【参考方案13】:

这里有一个提示,您可以如何使用 Netbeans 的功能来 创建将生成 scm-version.txt 的 自定义 ant 任务

打开您的 build.xml 文件,然后在 &lt;import file="nbproject/build-impl.xml"/&gt;

之后添加以下代码
<!-- 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 每次您进行 clean/build

您可以通过以下方式在运行时读取文件:

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

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

【讨论】:

【参考方案14】:

我使用MSBuild Community Tasks 项目,它有一个工具来检索SVN 修订号并将其添加到您的AssemblyInfo.vb。然后,您可以使用反射来检索此字符串以将其显示在您的 UI 中。

这是full blog post with instructions。

【讨论】:

【参考方案15】:

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

【讨论】:

【参考方案16】:

我在 CodePlex 上为 Build Version Increment 项目创建了一个 SVN version plug-in。这个 SVN 插件将从您的工作副本中提取最新的更改修订号,并允许您在您的版本号中使用它,这应该完全完成您正在尝试做的事情。 Build Version Increment 非常灵活,可让您以多种方式设置版本控制的完成方式。

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

【讨论】:

以上是关于如何访问当前的 Subversion 内部版本号?的主要内容,如果未能解决你的问题,请参考以下文章

将 subversion 存储库编号获取到代码中

如何在 build.gradle 中获取 Bamboo 内部版本号

SVN的目录说明

是否可以使用特定版本号进行subversion checkin?

如何从命令行签出特定的 Subversion 版本?

iOS - 如何使用 Fastlane 增加版本号?