如何确定根目录中最新的SVN修订版本号?

36

我想开始给我部署的二进制文件打上最新的 SVN 修订号。

然而,由于 SVN 是基于文件而不是基于目录/项目的,所以我需要扫描所有目录和子目录的文件,以确定最高的修订号。

在根目录上使用 svn info 不起作用(它只报告该目录的版本,而不是子目录中的文件):

我想知道是否有一种使用 svn 命令的快捷方式来解决这个问题。否则,有人能否建议一个简单的脚本,它具有网络效率(最好根本不要连接远程服务器)?

我还了解到,另一种替代方法是保留带有 svn:keywords版本文件。这个方法可行(我已经在其他项目上使用过它),但我厌倦了确保文件被修改并处理不可避免的合并冲突。

回答 我发现我的问题在于在调用根目录下的 svn info 之前没有进行适当的 svn up

$ svn info
Path: .
...
Last Changed Author: fak
Last Changed Rev: 713
Last Changed Date: 2008-08-29 00:40:53 +0300 (Fri, 29 Aug 2008)

$ svn up
At revision 721.

$ svn info
Path: .
...
Revision: 721
Last Changed Author: reuben
Last Changed Rev: 721
Last Changed Date: 2008-08-31 22:55:22 +0300 (Sun, 31 Aug 2008)
10个回答

25

第一种方法。当你检出代码时,请查看svn输出的最后一行:

$ svn up
...stuff...
Updated to revision 66593.

更加直接的方式:
$ svn info
Path: .
URL: https://svn.example.com/svn/myproject/trunk
Repository Root: https://svn.example.com/svn/
Repository UUID: d2a7a951-c712-0410-832a-9abccabd3052
Revision: 66593
Node Kind: directory
Schedule: normal
Last Changed Author: bnguyen
Last Changed Rev: 66591
Last Changed Date: 2008-09-11 18:25:27 +1000 (Thu, 11 Sep 2008)

我从未考虑过使用 svn up。然而,我不确定是否愿意将其放入部署脚本中。此外,svn info 无法工作,因为它只报告该目录,而不是子目录中的任何文件。不过还是谢谢您的建议! - Frank Krueger
忽略有关svn info的注释,我误解了svn up和svn info之间的交互。 - Frank Krueger

24

svnversion 似乎是最干净的方法:

svnversion -c /path/to/your-projects-local-working-copy/. | sed -e 's/[MS]//g' -e 's/^[[:digit:]]*://'

以上命令将清除输出中的任何M和S字母(表示本地修改或切换),以及较小的修订号,如果svnversion返回一个范围而不是一个修订号(有关更多信息,请参见文档)。如果您不想过滤输出,请去掉该命令中的管道和sed部分。

如果要使用svn info,则需要使用“递归”(-R)参数从子目录获取所有信息。由于输出结果变成了长列表,因此您需要进行一些过滤以获取所有变更中最高的最后更改修订号:

svn info -R /path/to/your-projects-local-working-copy/. | awk '/^Last Changed Rev:/ {print $NF}' | sort -n | tail -n 1

该命令的作用是获取所有包含字符串"Last Changed Rev"的行,然后从每行中除了最后一个字段(即修订版本号)以外的所有内容删除,接着将这些行按数值排序并删除除最后一行以外的所有内容,从而只得到最高的修订版本号。如果你运行的是Windows系统,我相信你也可以在PowerShell中轻松完成这个操作。

需要澄清的是:上述方法可以让你获得本地工作副本所代表的仓库路径的递归最后修改的修订版本号,只对于该本地工作副本有效,不会访问服务器。因此,如果有人在你上次执行svn update之后将某些内容更新到该路径的仓库服务器上,则此输出中不会反映出这些更改。

如果你想获取服务器上该路径的最后修改版本号,可以执行以下操作:

svn info /path/to/your-projects-local-working-copy/.@HEAD | awk '/^Last Changed Rev:/ {print $NF}'

7

这是一个与此问题重复的问题。正如我在那里发表的,svnversion命令是您的好朋友。无需解析输出,也无需先更新,它就可以完成工作。


1
svnversion -c 命令将给出该路径中最后更改的修订版本号。 - Robert Brisita

3

我不知道你是否在使用MSBuild(Visual Studio)来构建二进制文件。

但是,如果你使用的话,通过MSBuild Community Tasks Project可以在Subversion和MSBuild之间建立连接。

以下是我们构建脚本的一部分:我们的(C#)应用程序包含svn修订号:

  <SvnVersion LocalPath="$(MSBuildProjectDirectory)" ToolPath="installationpath\of\subversion\bin">
     <Output TaskParameter="Revision" PropertyName="Revision" />
  </SvnVersion>
  <Message Text="Version: $(Major).$(Minor).$(Build).$(Revision)"/>
...
    AssemblyVersion="$(Major).$(Minor).$(Build).$(Revision)"
     AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)"

一月


我不是,但我相信这些信息对那些需要的人很有帮助。谢谢! - Frank Krueger

2

Subversion中有一个名为svnversion的程序,可以完美地实现你想要做的事情。这就是我们标记网站的方式。


2
@Charles Miller和@Troels Arvin提供的答案是正确的- 您可以使用svn updatesvn info 的输出,但正如您所暗示的那样,如果存储库是最新的,则后者只适用于此。然而,如果源代码树的某部分与另一部分处于不同的修订版本上,我不确定任何修订版本对您有什么价值。对我来说,这真的听起来像您应该在一个同质树上工作。
我建议在运行info之前更新(或者如果您已经为构建更新了,那就是完美的),或者使用svn info URL-to-source

2

如果你只想要最新提交的修订号,并且在Windows上不使用grep/awk/xargs,那么这里是运行的基本命令(命令行):

X:\trunk>svn info -r COMMITTED | for /F "tokens=2" %r in ('findstr /R "^Revision"') DO @echo %r
67000

svn info -r COMMITTED 可以给你当前目录的最新提交版本:

X:\Trunk>svn info -r COMMITTED
Path: trunk
URL: https://svn.example.com/svn/myproject/trunk
Repository Root: https://svn.example.com/svn/
Repository UUID: d2a7a951-c712-0410-832a-9abccabd3052
Revision: 67400
Node Kind: directory
Last Changed Author: example
Last Changed Rev: 67400
Last Changed Date: 2008-09-11 18:25:27 +1000 (Thu, 11 Sep 2008)

这个for循环运行findstr来定位svn info输出中的版本部分。它的输出将是(您看不到这个):

Revision: 67000

然后它会分割令牌,并返回第二个令牌,以便被echo输出:

67000

1

对我来说,查找主干/分支的最后修订号码的最佳方法是从远程URL获取它。重要的是不要使用工作目录,因为它可能已经过时了。这里有一个批处理片段(我讨厌很多;-)):

@for /f "tokens=4" %%f in ('svn info %SVNURL% ^|find "Last Changed Rev:"') do set lastPathRev=%%f

echo trunk rev no: %lastPathRev%

然而,我有一个问题,即将这个数字硬编码为包含$Rev:$的源代码中的临时版本。问题在于$Rev:$包含文件版本号。因此,如果主干版本号大于版本文件的版本号,则需要“人为地”修改此文件并提交以获得正确的临时版本(=主干版本)。这很烦人!有没有更好的想法?非常感谢。


1
"

"svn info" 会显示工作副本的版本号(请查看 "svn info" 输出中的 "Revision" 行)。您的构建系统可能允许您将 "svn info" 输出的相关部分放置在应用程序中会反映的某个地方。例如,您可以指定在构建时应创建一个临时的(非版本化的)文件,其中包含来自 "svn info" 的输出;然后在编译时包含此文件。

"

啊,看起来我误解了 svn up 和 svn info 的交互作用。感谢让我测试我的假设! - Frank Krueger

0

这很荒谬,但是svn infosvnversion不会考虑子目录;这是一个名为工作'Mixed Revisions'的功能 - 我称之为折磨。我只需要找到最新的生产代码库'revision',下面的黑客方式适用于我 - 运行可能需要一段时间:

repo_root# find ./ | xargs -l svn info  | grep 'Revision: ' | sort
...
Revision: 86
Revision: 86
Revision: 89
Revision: 90
root@fairware:/home/stage_vancity#

1
“Mixed WC”是你的选择,没有人强制你走这种(丑陋)的开发方式。 - Lazy Badger

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