关于构建自动化:如何确定植根于目录中的最新SVN版本号?

关于构建自动化:如何确定植根于目录中的最新SVN版本号?

How do you determine the latest SVN revision number rooted in a directory?

我想开始用最新的SVN版本号标记已部署的二进制文件。

但是,由于SVN是基于文件的,而不是基于目录/项目的,因此我需要浏览所有目录和子目录的文件,以确定最高的修订号。

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

我想知道是否存在使用svn命令执行此操作的快捷方式。否则,有人可以建议一个简单的网络高效脚本(如果它根本不影响远程服务器的话,我会更喜欢)?

我也了解一种替代方法是使用svn:keywords保留版本文件。这行得通(我已经在其他项目上使用过它),但是我厌倦了确保文件不脏以及不可避免的合并冲突。

回答我看到我的问题在于在根目录中调用svn info之前没有执行正确的svn up

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ 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)


单程。当您签出代码时,请看svn输出的最后一行:

1
2
3
$ svn up
...stuff...
Updated to revision 66593.

更直接的方法:

1
2
3
4
5
6
7
8
9
10
11
$ 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)

svnversion似乎是最干净的方法:

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

上面的命令将从输出中清除所有M和S字母(指示本地修改或切换),以及较小的修订号,以防svnversion返回一个范围而不是一个修订号(有关详细信息,请参阅文档) )。如果不想过滤输出,请取出管道和该命令的sed部分。

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

1
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之后将此路径中的某些内容更新到存储库服务器中,则该内容将不会反映在此输出中。

如果您想要的是服务器上此路径的最后更改版本,则可以执行以下操作:

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


这个问题重复。正如我在此处发布的,svnversion命令是您的朋友。无需解析输出,无需先更新,即可完成工作。


我不知道您是否使用MSBuild(Visual Studio)构建二进制文件。
但是,如果您愿意:
Subverion和MSBuild之间可能存在连接
MSBuild社区任务项目

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

1
2
3
4
5
6
7
  <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)"

一月


如果您只想提交已提交的最新更改的修订版号,并且正在使用不带grep / awk / xargs的Windows,则可以运行以下命令(命令行):

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

svn info -r COMMITTED将为您提供对当前目录的最新提交更改:

1
2
3
4
5
6
7
8
9
10
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输出的修订版本。这样的输出将是(您将不会看到):

1
Revision: 67000

然后拆分令牌,并返回第二个,以echo删除:

1
67000

有一个与Subversion一起发行的名为svnversion的程序,可以完成您想做的事情。这就是我们标记网站的方式。


@Charles Miller和@Troels Arvin提供的答案是正确的-您可以使用svn updatesvn info的输出,但是正如您所暗示的,后者仅在存储库是最新的时才有效。再说一遍,如果源树的一部分与另一部分不在同一版本上,则我不确定任何修订号将给您带来什么价值。在我看来,确实听起来像您应该在同质树上工作。
我建议要么在运行信息之前进行更新(或者如果您已经为自己的版本进行了更新,那么您就很满意),或者建议使用svn info URL-to-source


对我而言,找出主干/分支的最新修订号的最佳方法是从远程URL获取它。重要的是不要使用工作目录,因为它可能已过时。这是一个带有批处理的代码段(我非常讨厌;-)):

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

echo trunk rev no: %lastPathRev%

但是,我很难将这个数字作为临时版本硬编码到包含$ Rev:$的源中。问题是$ Rev:$包含文件rev。没有。因此,如果trunk rev no大于版本文件的rev no,我需要"人为地"修改此文件并提交以获取正确的临时版本(= trunk版本)。这是一个窗格!有人有更好的主意吗?
非常感谢


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


这太荒谬了,但是svn infosvnversion不会考虑子目录。这是一个称为"混合修订"的功能-我称之为酷刑。我只需要找到实时代码库的最新"修订",下面的黑手工作对我来说就可以了-运行可能需要一段时间:

1
2
3
4
5
6
7
repo_root# find ./ | xargs -l svn info  | grep 'Revision: ' | sort
...
Revision: 86
Revision: 86
Revision: 89
Revision: 90
root@fairware:/home/stage_vancity#


推荐阅读