如何以编程方式获取SVN版本号?

7

像这个问题,但不需要实际查询SVN服务器。这是一个基于Web的项目,所以我想我会将仓库用作公共视图(除非有人能告诉我这是一个坏主意)。我假设这些信息在.svn文件夹的某个文件中,但在哪里,以及如何解析它?我想做类似于SO的事情,在右下角显示版本号。

如果您手头有Python或PHP代码,或者只是指点正确的方向,那将不胜感激。

9个回答

13

为了达到这个目的,Subversion包含了svnversion工具。工作副本可能实际上有本地修改或由多个版本混合而成。svnversion知道如何处理它; 请参阅链接文档中的示例。

你可以像这样从Python中调用svnversion

import subprocess

def svnversion():
    p = subprocess.Popen("svnversion", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (stdout, stderr) = p.communicate()
    return stdout

为什么要使用 shell=True?请参见 https://docs.python.org/2/library/subprocess.html#frequently-used-arguments - lorenzog
@lorenzog:这个回答已经有将近7年的历史了,所以我不记得了。如果你已经验证过它可以在没有shell=True的情况下工作,那么请告诉我,我会将其编辑掉。 - Wim Coenen
对我来说,它似乎工作得很好:http://stackoverflow.com/a/37157630/204634(由于某种原因,我无法@你的昵称..?) - lorenzog

4

我无法确定你是否在讽刺,但对我来说,这比通过 shell 或 socket 连接到 SVN 然后解析大量输出要高效得多。 - glomad
不,完全不是。我并不是那个意思 :) - mpen
我的意思是,这听起来比在每个页面加载时运行外部进程要高效得多。我认为读取文本文件实际上会更有效率。 - mpen

3
您可以使用命令行中的"svn info"获取检出的当前修订版本号。
例如:
$ svn info
Chemin : .
URL : http://.../trunk
Racine du dépôt : http://...
UUID du dépôt : 128b9c1a-...-612a326c9977
Révision : 185
Type de nœud : répertoire
Tâche programmée : normale
Auteur de la dernière modification : ...
Révision de la dernière modification : 185
Date de la dernière modification: 2009-09-28 20:12:29 +0200 (lun. 28 sept. 2009)

请注意这是本地化的;如果您使用的是Linux系统,可以尝试使用以下命令:
$ LANG=en svn info
svn: warning: cannot set LC_CTYPE locale
svn: warning: environment variable LANG is en
svn: warning: please check that your locale name is correct
Path: .
URL: http://.../trunk
Repository Root: http://...
Repository UUID: 128b9c1a-...-612a326c9977
Revision: 185
Node Kind: directory
Schedule: normal
Last Changed Author: mzeis
Last Changed Rev: 185
Last Changed Date: 2009-09-28 20:12:29 +0200 (Mon, 28 Sep 2009)

如果在PHP中使用这个功能,将其作为XML可能更有帮助(更容易解析,并且不受区域设置的影响):
$ svn info --xml
<?xml version="1.0"?>
<info>
<entry
   kind="dir"
   path="."
   revision="185">
<url>http://.../trunk</url>
<repository>
<root>http://...</root>
<uuid>128b9c1a-...-612a326c9977</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit
   revision="185">
<author>...</author>
<date>2009-09-28T18:12:29.130307Z</date>
</commit>
</entry>
</info>

只需使用 simplexml_load_string,并获取 entry 标签的 revision 属性。请注意,不建议在每个页面视图上执行此操作:速度不如您的应用程序所希望的那样快。相反,我会在创建归档文件时获取修订版本号,稍后将其发送到生产服务器,并将其存储在某种配置文件中。这样,您就不需要在生产服务器上使用 svn 命令,也不需要在该服务器上进行检出。

我本来希望有一种不需要解析 svn info 的方法,但我想这也是一个有效的解决方案。它可能比解析文件产生更一致的信息... 我之前不知道 --xml 选项,这应该会让事情变得更容易。 - mpen

3

这适用于svn版本1.6.2。但请注意,不同的SVN版本使用不同格式的.svn文件夹。

<?php

$contents = file_get_contents(dirname(__FILE__) . '/.svn/entries');
preg_match("/dir\n(.+)/", $contents, $matches);
$svnRevision = $matches[1];

print "This Directory's SVN Revsion = $svnRevision\n";

3
以下是一个命令行单行代码,跟随Lance。
svn log -q --limit 1  http://svnbox/path/to/repo/trunk \
| php -r 'fgets(STDIN); preg_match("/(\d+)/", fgets(STDIN), $m); echo $m[0];'

2
如果你正在寻找 Python 实现,可以查看 pysvn,你可以调用 info 命令 获取包括当前版本在内的详细信息:
entry = info( path )

2

1

我知道这个问题很老了,但是我想提供一下我在我的Web应用程序中如何使用PHP实现这个功能:

将以下代码放入您的应用程序中的PHP文件中,并设置SVN关键字属性为“Date Revision Author HeadURL Id”(文件中的关键字替换)。

$SVN_rev = "\$LastChangedRevision$";
$SVN_headURL = "\$HeadURL$";

function stripSVNstuff($s)
{
    $s = substr($s, strpos($s, ":")+1);
    $s = str_replace("$", "", $s);
    return trim($s);
}

所以在svn对源文件进行关键字替换后,$SVN_rev行将如下所示:

$SVN_rev = "\$LastChangedRevision: 6 $";

因此,stripSVNstuff($SVN_rev)的输出将是“6”(不带引号)。


0

你可以直接在命令行中运行 svn info 命令。但请记住,这可能是一个混合版本。你也可以运行 svn up 命令,STDOUT 的最后一行将给出修订号。

或者,你想使用 svn API 吗?你还可以查看 TortoiseSVN 代码中的 SubWCRev,它用于将文件中的令牌替换为 WC 的当前修订版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接