使用Git/SVN为代码添加前缀“?<revision-number>”

12

如何使用Git/SVN高效地将前缀?v=VersionNumber添加到代码仓库中的每个文件?

我发现SO在其代码仓库中为每个特定文件赋予版本号。

他们使用SVN。我想知道如何使用Git实现相同的功能。

以下是一些示例。

#1

<link rel="stylesheet" href="/content/all.css?v=3959">

#2

<script src="./js/question.js?v=3955" type="text/javascript"></script>

1
刚刚添加了一些注释以回复您的评论。 - VonC
1
添加了一条评论以回复您的评论,询问为什么要显示 SVN 版本号。 - VonC
4个回答

15
"在你的存储库中"? 直接在你的存储库中进行? 这将被称为 "关键字扩展",不建议这样做(如此SO问题所讨论)。
将元数据(修订号)放入存储在存储库中的数据中可能会导致合并问题
在SO页面中看到的是部署过程的结果,该过程从SVN(修订版)中获取元数据,并将其放入生成的HTML页面中。 GitFaq也不建议使用关键词扩展。在服务器上部署的文件中集成类似于SVN修订号的内容,应使用git describe,以便在部署步骤中显示某种“提交计数”。
但是,直接记录在存储库中将意味着关键字扩展和关键字非扩展。
为了说明这一点,让我们看看Linus在这个话题的最初讨论(2007年4月)时说了什么:

添加扩展不仅“更难”。从任何性能来看,它基本上都是不可能的。
想想 "git checkout newbranch"。
再想想我们对于没有改变的文件(以及整个子目录!)要进行什么操作。最后,考虑在支持分支的SCM git中这种优化有多重要。

[关键字扩展存在的]根本问题(例如,在没有检查设置“关键字”属性的每个单个文件的情况下,切换分支基本上是不可能的。还有其他问题)。

现在,取消扩展很容易实现(实际上与“CRLF->LF”转换完全相同:从技术上讲,这也是一种“取消扩展”)。而且应该可以工作。

这种方法还会破坏“git diff”,因为它基本上总是使diff忽略关键字。换句话说,当你执行时

git diff A..B
并且将差异发送给其他人,他们根本看不到任何关键字!现在,这显然满足了我如果A和B相同则差异为空的要求,因此您应该期望我很高兴。但我并不满意,因为如果另一个人也在使用git,则他甚至无法应用差异!即使他处于“A”状态,并因此获得了应该准确应用的差异,如果未展开关键字周围存在其他更改(当然,他将在工作树中展开它们!),他也将收到拒绝。你明白吗?关键字根本行不通。它们是有问题的。您可以忽略它们(不在差异中显示它们),在这种情况下,差异是错误的;或者您可以不忽略它们(并在差异中显示它们),在这种情况下,差异也是错误的,只是不同而已。唯一明智可行的情况是根本没有它们。任何关键字扩展都将始终导致问题。您根本没法做到正确。

@VonC:你的回答引发了一个问题。你在项目中使用的是哪个功能来替代“关键字扩展”?--- 我从未在我的项目中使用过它。 - Léo Léopold Hertz 준영
我很惊讶为什么SO使用“关键字扩展”。这背后一定有一些原因。也许,他们不使用git-svn,这导致他们使用“关键字扩展”。 - Léo Léopold Hertz 준영
@Masi:在你的问题背景下,可以使用“git describe”命令获取某种技术版本号(例如,在部署阶段将其包含到文件中)。 - VonC
1
@Masi: 我的观点是:我认为SO根本不使用关键字扩展,而是在一个被PHP脚本读取的文件中使用已知的SVN修订号码,并生成正确的HTML页面。这只是在部署后替换正确的变量,而不是在提交时嵌入元数据(关键字扩展)的问题。 - VonC
@VonC:他们为什么要这样做?--- 是为了混淆新手吗?还是为了让非程序员看到当前版本号的一种方式? - Léo Léopold Hertz 준영
2
@Masi:允许用户说出你的技术版本“SVN修订号”,Stackoverflow网站有这样那样的问题。然后SO团队可以将该修订号复制到一个SVN“BugFix”分支中并开始修复错误。这是公共部署网站(“分布式”文件,不存储但生成)和内部数据(“开发”文件,在SVN仓库中存储)之间的链接。 - VonC

6
如果这个版本号是由一些服务器脚本(如PHP、Perl、ASP.NET、Ruby on Rails)生成的,那么只需在此脚本中运行git describe即可。VonC解释为什么关键字扩展是一个坏主意,即为什么让Git而不是Web服务器更新这些信息是一个坏主意。
另一个解决方案是制作部署(构建)系统,将文件从版本控制系统复制到Web服务器,并嵌入这些数据。例如,用Perl编写的Git Web界面gitweb就有这个功能。
our $version = "++GIT_VERSION++";

由构建系统 (make gitweb/gitweb.cgi) 替换,通过运行 GIT-VERSION-GEN 的结果来实现。这意味着例如运行 gitweb 时会在 "generator" 元数据头中显示:

<meta name="generator" content="gitweb/1.6.4.rc0.22.gfc1cf.dirty git/1.6.3.2.317.g2dd3f"/>

2
也许您正在寻找这个: 如何为Git repos启用标识字符串? 至少可以设置$Id$,并且使用过滤器将允许您有更多选项。
示例(不是最佳示例)来自此答案
echo '*.txt ident' >> .gitattributes
echo '$Id$' > test.txt
git commit -a -m "test"

rm test.txt
git checkout -- test.txt
cat test.txt

请参阅Git属性手册


谢谢您的回答!我在这里添加了一个示例以增加一些具体性。可能还有更好的例子适用于此。 - Léo Léopold Hertz 준영

1
忽略你问题中的“高效”一词,你应该查找“过滤驱动程序”。简单地插入修订并进行清理以删除它应该可以实现你(认为你)想要的效果。

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