34

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

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

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

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

我也知道另一种方法使用svn:keywords. 这行得通(我在其他项目中使用过),但我厌倦了处理确保文件脏和处理不可避免的合并冲突。

回答svn up我发现我的问题在于在调用svn info根目录之前没有做正确的事情:

$ 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)
4

10 回答 10

23

单程。查看代码时,请查看 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)
于 2008-09-11T10:43:00.050 回答
22

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

该命令的作用是获取包含 string 的所有行"Last Changed Rev",然后从每一行中删除除最后一个字段(即修订号)之外的所有内容,然后对这些行进行数字排序并删除除最后一行之外的所有内容,结果仅在最高修订号中。例如,如果您运行的是 Windows,我相信您也可以在 PowerShell 中轻松完成此操作。

只是要清楚一点:上述方法为您提供了本地工作副本所代表的存储库中路径的递归最后更改修订号,对于该本地工作副本,而无需访问服务器。因此,如果有人在您的 last 之后将此路径中的某些内容更新到存储库服务器上svn update,它将不会反映在此输出中。

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

svn info /path/to/your-projects-local-working-copy/.@HEAD | awk '/^Last Changed Rev:/ {print $NF}'
于 2008-10-30T11:44:17.467 回答
7

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

于 2008-10-30T13:59:21.440 回答
3

我不知道您是否使用 MSBuild(Visual Studio) 来构建二进制文件。但如果你愿意:Subverion 和 MSBuild 之间可能通过 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)"

于 2008-09-11T10:54:47.900 回答
2

@Charles Miller 和 @Troels Arvin 提供的答案是正确的 - 您可以使用svn updateor的输出svn info,但正如您所暗示的,后者仅在存储库是最新的情况下才有效。再说一次,如果您的源代码树的一部分与另一部分位于不同的修订版上,我不确定任何修订号对您有什么价值。在我看来,这听起来真的像是你应该在一棵同质树上工作。我建议在运行 info 之前进行更新(或者如果您已经为您的构建进行了更新,那么您就是黄金)或使用svn info URL-to-source.

于 2008-09-11T11:00:00.413 回答
2

有一个随 Subversion 一起分发的程序,称为svnversion,它完全可以满足您的需求。这就是我们标记网站的方式。

于 2008-10-30T14:00:19.520 回答
2

如果您只想要提交的最新更改的修订号,并且使用没有 grep/awk/xargs 的 Windows,这里是运行的基本命令(命令行):

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以定位输出的 Revision 部分svn info。输出将是(你不会看到这个):

Revision: 67000

然后拆分令牌,并返回第二个,以被echo淘汰:

67000
于 2015-12-02T16:36:28.873 回答
1

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

于 2008-09-11T10:43:47.597 回答
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:$ 包含文件 rev。不。因此,如果中继版本号大于版本文件的版本号,我需要“人为”修改此文件并提交它以获得正确的临时版本(=中继版本)。这是一个窗格!有人有更好的主意吗?非常感谢

于 2013-01-16T21:46:29.170 回答
0

这很荒谬,但svn infosvnversion不会考虑子目录;这是一个名为“混合修订”的功能——我称之为折磨。我只需要找到实时代码库的最新“修订版”,下面的破解方式对我有用 - 运行可能需要一段时间:

repo_root# find ./ | xargs -l svn info  | grep 'Revision: ' | sort
...
Revision: 86
Revision: 86
Revision: 89
Revision: 90
root@fairware:/home/stage_vancity#
于 2012-10-24T20:17:33.760 回答