TortoiseSVN关键字替换何时发生?

时间:2013-11-10 15:47:04

标签: svn tortoisesvn

关键字替换何时发生? 如何设置

我设置svn:keywords属性

我将这些行放在1.txt中并提交它。

$Revision$
$Author$

2 个答案:

答案 0 :(得分:1)

当且仅当设置了适当的svn:keywords值时,才会在文件的checkout / update / switch / export / cat上展开关键字。当提交包含关键字的文件时,客户端将关键字降低为关键字字符串的空副本并将其发送到服务器。除非设置svn:keywords属性,否则Subversion不启用关键字的原因是Subversion将永远不会更改您的文件内容,除非您告诉我们这样做,属性。

考虑Subversion的INSTALL文档。它将svn:keywords属性设置为LastChangedDate。如果从此URL检索具有HTTP(而不是Subversion客户端)的文件: https://svn.apache.org/repos/asf/subversion/trunk/INSTALL

您会注意到该文件只有$LastChangedDate$,并且未展开。这是存储在服务器中的文件的表示形式。从1.8.0开始,我们为服务器提供了一个附加选项,允许HTTP客户端请求扩展关键字。因此,如果您访问了以下网址,则会看到关键字已展开: https://svn.apache.org/repos/asf/subversion/trunk/INSTALL?kw=1

您还可以使用Subversion客户端的cat命令检索文件并为您执行关键字替换(例如 svn cat https://svn.apache.org/repos/asf/subversion/trunk/INSTALL)。

关键字在展开时展开的值基于上次更改文件的修订版本的修订版属性。修订版属性通常在提交时设置(尽管修订版属性可能会在以后更改) )。那么你在输出中得到的值取决于扩展完成时的值。 HeadURL属性当然也是存储库访问方式的属性。 Revision可能永远不会改变。

如果您打算使用它们,我建议您阅读section about keyword substitution in the SVN Book

答案 1 :(得分:-2)

Subversion在提交期间设置关键字。试试svn update,看看是否能解决问题。

Subversion关键字替换是服务器功能。有关Subversion online manual中的工作原理的文档。确保svn:keywords包含您需要的关键字,正确大写,空格分隔以及没有美元符号。例如

$ svn propset svn:keywords "Revision Author" myfile.txt

而不是

$ svn propset svn:keywords "revision author" myfile.txt     # Wrong capitalization
$ svn propset svn:keywords "$Revision$ $Author$" myfile.txt # $ should not be included
$ svn propset svn:keywords "Revision  Author" myfile.txt    # No commas

而且,现在我的咆哮......


RCS关键字危险

好的,他们不会捅你的眼睛。但是,它们并不是那么有用,并且会在开发中引起各种各样的问题。

RCS创建了您看到的当前关键字。 RCS实际上没有完整存储库的概念,并且没有简单的方法来查看诸如作者姓名或特定文件的RCS修订号之类的信息。关键字会支持这一点。

Subversion不需要关键字,因为Subversion具有竞争存储库的概念。如果您正在编辑文件并想知道作者是谁,或者是什么版本,那么您只需对该文件svn info进行操作。

然而,旧的习惯会变得很难,Subversion会让你能够支持一些不那么糟糕的RCS关键词(它不会支持$Log$,这可能会成为一个递归的噩梦。有人在提交注释中添加了$Log$。)因为一些管理员(也就是无知的奇迹)坚持关键字很重要,如果版本控制系统不支持它们,那就不好了。

那么,使用关键字有什么害处?

想象一下你做了一个分支:

$ svn cp trunk/proj ../branches/2.3/proj

现在,稍后您想看到您在该分支上所做的更改以及它与主干的不同之处:

$ svn diff $REPO/trunk/proj $REPO/branches/2.3/proj

嗯......看起来该分支上的每个文件都已被更改。也许我应该做一个差异...

$ svn diff $REPO/trunk/proj/foo.txt $REPO/branches/2.3/proj/foo.txt

+ /trunk/proj/foo.txt
- /trunk/branches/2.3/proj/foo.txt

+ /* $Revision: 23293$ */
- /* $Revision: 25329$ */

哦......整个差异就是我在程序中嵌入的RCS关键字。现在,除了RCS关键字之外,我绝对无法知道实际更改了哪些文件以及哪些文件没有更改。

顺便说一下,执行svn merge时,每个关键字更改都会显示为冲突。您将花费20分钟处理此冲突,这最终是绝对无意义的,因为当您执行提交时,关键字将再次更改。

因此,使用Subversion时使用RCS关键字几乎没有什么好处,如果你使用它们会有很多痛苦。

但是,如果我不在Subversion之外怎么办?

是的,如果您在客户端系统上,则使用RCS关键字来确定文件的版本。实际上,RCS ident命令可以搜索特定的$ Id $字符串。实际上,甚至还有一个名为ident的特殊命令,可以让您快速查看RCS ID。例如,我想知道我/bin/ksh中使用的修订版:

$ ident /bin/ksh
/bin/ksh
$Id: enum (AT&T Research) 2008-01-08 $
$Id: type (AT&T Labs Research) 2008-01-08 $
$Id: type (AT&T Labs Research) 2008-07-01 $
$Id: test (AT&T Research) 2003-03-18 $
$Id: break (AT&T Research) 1999-04-07 $
$Id: continue (AT&T Research) 1999-04-07 $
$Id: alias (AT&T Research) 1999-07-07 $
$Id: builtin (AT&T Research) 2010-08-04 $
$Id: cd (AT&T Research) 1999-06-05 $
$Id: command (AT&T Research) 2003-08-01 $
$Id: (AT&T Research) 2000-04-02 $
$Id: eval (AT&T Research) 1999-07-07 $
$Id: exec (AT&T Research) 1999-07-10 $
$Id: exit (AT&T Research) 1999-07-07 $
$Id: export (AT&T Research) 1999-07-07 $
$Id: getopts (AT&T Research) 2005-01-01 $
$Id: bg (AT&T Research) 2000-04-02 $
$Id: fg (AT&T Research) 2000-04-02 $
$Id: disown (AT&T Research) 2000-04-02 $
$Id: jobs (AT&T Research) 2000-04-02 $
$Id: hist (AT&T Research) 2000-04-02 $
$Id: kill (AT&T Research) 1999-06-17 $
$Id: let (AT&T Research) 2000-04-02 $
$Id: print (AT&T Research) 2008-11-26 $
$Id: printf (AT&T Research) 2009-02-02 $
$Id: pwd (AT&T Research) 1999-06-07 $
$Id: read (AT&T Research) 2006-12-19 $
$Id: readonly (AT&T Research) 2008-06-16 $
$Id: return (AT&T Research) 1999-07-07 $
$Id: sh (AT&T Research) 93u 2011-02-08 $
$Id: set (AT&T Research) 1999-09-28 $
$Id: shift (AT&T Research) 1999-07-07 $
$Id: sleep (AT&T Research) 2009-03-12 $
$Id: trap (AT&T Research) 1999-07-17 $
$Id: typeset (AT&T Research) 2010-12-08 $
$Id: ulimit (AT&T Research) 2003-06-21 $
$Id: umask (AT&T Research) 1999-04-07 $
$Id: unset (AT&T Research) 1999-07-07 $
$Id: unalias (AT&T Research) 1999-07-07 $
$Id: wait (AT&T Research) 1999-06-17 $
$Id: whence (AT&T Research) 2007-04-24 $
$Id: regex (AT&T Research) 2010-09-22 $
$Id: basename (AT&T Research) 2010-05-06 $
$Id: cat (AT&T Research) 2010-04-11 $
$Id: chmod (AT&T Research) 2010-07-28 $
$Id: cmp (AT&T Research) 2010-04-11 $
$Id: cut (AT&T Research) 2010-08-11 $
$Id: dirname (AT&T Research) 2009-01-31 $
$Id: getconf (AT&T Research) 2008-04-24 $
$Id: head (AT&T Research) 2006-09-27 $
$Id: logname (AT&T Research) 1999-04-30 $
$Id: mkdir (AT&T Research) 2010-04-08 $
$Id: sync (AT&T Research) 2006-10-04 $
$Id: uname (AT&T Research) 2007-04-19 $
$Id: wc (AT&T Research) 2009-11-28 $
$Id: Version JM 93u 2011-02-08 $
$Id: libcoshell (AT&T Research) 2010-05-19 $

是的,这很有帮助......

有很多问题:

  • 编译后的程序可以由数十个(如果不是数百个)单个文件组成。正如您从上面所看到的,在这些中使用RS关键字并不是那么有用。
  • 编译代码优化 ID字符串。
  • 开发人员必须记住包含它。
  • 即使一切都完美无缺,但它并没有告诉您最有用的信息:我在看什么 RELEASE 。版本可以由多个文件,程序,配置文件等组成。它们彼此交互。了解一些RCS关键字并没有给你太多帮助。您需要整个版本的官方修订版号,而不是单个文件。

当您为正式版本进行编译或打包时,您需要的是生成此正式版本的方法。在我们公司,我们使用Jenkins作为持续集成引擎。除非Jenkins 构建,否则不会向客户发布任何版本。这包括不编译的JavaScript和Perl项目。

我们创建了某种类型的 build 文件,该文件始终打包在我们的构建中。一个相当简单的可能看起来像这样:

Jenkins Project: %JOB_NAME%
Jenkins Build:   %BUILD_NUMBER%

当Jenkins进行构建时,它会设置环境变量JOB_NAMEBUILD_NUMBER。当我在Jenkins上构建时,我让Jenkins复制并过滤此文件,用实际的Jenkins作业替换%...%占位符并构建:在我的Jenkins构建之后,文件看起来像这样:

Jenkins Project: foo-3.4
Jenkins Build:   233

这可能是我系统上的某个文件,或者我可以嵌入它,因此当用户查看 about box 时它会显示出来。这将我的包裹追溯到正式版本。从该正式版本开始,我可以生成发行说明并查看更改内容。我可以使用标签返回并获取整个项目和所有各种文件进行测试,以查看可能导致错误的原因。这比随机Subversion版本号更有用。并且,我没有RCS关键字在Subversion中导致的缺点。