什么时候发生关键字替换?如何设置
我设置svn:keywords
属性
我将这些行放在 1.txt 中并提交。
$Revision$
$Author$
当且仅当svn:keywords
设置了适当的值时,关键字才会在文件的 checkout/update/switch/export/cat 上展开。当提交包含关键字的文件时,客户端将关键字缩减为关键字字符串的空副本并将其发送到服务器。Subversion 不启用关键字的原因,除非svn:keywords
设置了属性,否则 Subversion 永远不会更改您的文件内容,除非您告诉我们这样做,该属性会这样做。
考虑 Subversion 的 INSTALL 文档。它的svn:keywords
属性设置为LastChangedDate
。如果您从以下 URL 使用 HTTP(而不是 Subversion 客户端)检索文件:
https ://svn.apache.org/repos/asf/subversion/trunk/INSTALL
您会注意到该文件只有$LastChangedDate$
并且没有展开。这是存储在服务器中的文件的表示。从 1.8.0 开始,我们为服务器添加了一个选项,允许 HTTP 客户端请求扩展关键字。因此,如果您访问以下 URL,您将看到关键字已扩展:
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
可能永远不会改变。
如果您要使用它们,我建议您阅读SVN Book 中关于关键字替换的部分。
Subversion 在提交期间设置关键字。尝试一下svn update
,看看是否可以解决。
Subversion 关键字替换是一个服务器特性。Subversion 在线手册中有关于它如何工作的文档。确保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 修订号之类的信息。关键字将支持这一点。
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 关键字几乎没有什么好处,而如果您确实使用它们会很痛苦。
是的,如果您在客户端系统上,RCS 关键字用于确定文件的版本。实际上,RCSident
命令可以搜索特定的 $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 $
是的,这很有帮助...
有多个问题:
当您为正式版本进行编译或打包时,您需要一种生成此正式版本的方法。在我们公司,我们使用Jenkins作为我们的持续集成引擎。除非由 Jenkins构建,否则不会向客户发布任何版本。这包括无法编译的 JavaScript 和 Perl 项目。
我们创建了某种类型的构建文件,该文件始终打包在我们的构建中。一个相当简单的可能看起来像这样:
Jenkins Project: %JOB_NAME%
Jenkins Build: %BUILD_NUMBER%
当 Jenkins 进行构建时,它会设置环境变量JOB_NAME
和BUILD_NUMBER
. 当我在 Jenkins 上进行构建时,我让 Jenkins 复制并过滤此文件%...%
,用实际的 Jenkins 作业替换占位符并构建:在我的 Jenkins 构建之后,文件将如下所示:
Jenkins Project: foo-3.4
Jenkins Build: 233
这可能是我系统上某处的文件,或者我可以嵌入它,因此当用户查看about 框时它会显示出来。这将我的包追溯到正式版本。从该官方版本中,我可以生成发行说明并查看更改了哪些内容。我可以使用标签返回并获取整个项目和所有各种文件以进行测试,以查看可能导致错误的原因。这比随机的 Subversion 修订号更有用。而且,我没有 RCS 关键字在 Subversion 中造成的缺点。