使用 git-svn 处理 SVN 关键字扩展
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/62264/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dealing with SVN keyword expansion with git-svn
提问by Will Robertson
I recently asked about keyword expansion in Gitand I'm willing to accept the design not to really support this idea in Git.
我最近询问了Git 中的关键字扩展,我愿意接受这样的设计,它并不真正支持 Git 中的这个想法。
For better or worse, the project I'm working on at the moment requires SVN keyword expansion like this:
不管好坏,我目前正在做的项目需要像这样的 SVN 关键字扩展:
svn propset svn:keywords "Id" expl3.dtx
to keep this string up-to-date:
保持这个字符串是最新的:
$Id: expl3.dtx 803 2008-09-11 14:01:58Z will $
But I would quite like to use Git to do my version control. Unfortunately, git-svn doesn't support this, according to the docs:
但我很想用 Git 来做我的版本控制。不幸的是,根据文档,git-svn 不支持这一点:
"We ignore all SVN properties except svn:executable"
“我们忽略除 svn:executable 之外的所有 SVN 属性”
But it doesn't seem too tricky to have this keyword stuff emulated by a couple of pre/post commit hooks. Am I the first person to want this? Does anyone have some code to do this?
但是通过几个提交前/提交后挂钩来模拟这个关键字的东西似乎并不太棘手。我是第一个想要这个的人吗?有没有人有一些代码来做到这一点?
采纳答案by emk
What's going on here: Git is optimized to switch between branches as quickly as possible. In particular, git checkoutis designed to not touch any files that are identical in both branches.
这里发生了什么:Git 经过优化,可以尽快在分支之间切换。特别是,git checkout旨在不接触两个分支中相同的任何文件。
Unfortunately, RCS keyword substitution breaks this. For example, using $Date$would require git checkoutto touch every file in the tree when switching branches. For a repository the size of the Linux kernel, this would bring everything to a screeching halt.
不幸的是,RCS 关键字替换打破了这一点。例如,使用$Date$将需要git checkout在切换分支时接触树中的每个文件。对于 Linux 内核大小的存储库,这将使一切都戛然而止。
In general, your best bet is to tag at least one version:
一般来说,最好的办法是标记至少一个版本:
$ git tag v0.5.whatever
...and then call the following command from your Makefile:
...然后从您的 Makefile 中调用以下命令:
$ git describe --tags
v0.5.15.1-6-g61cde1d
Here, git is telling me that I'm working on an anonymous version 6 commits past v0.5.15.1, with an SHA1 hash beginning with g61cde1d. If you stick the output of this command into a *.hfile somewhere, you're in business, and will have no problem linking the released software back to the source code. This is the preferred way of doing things.
在这里,git 告诉我我正在处理 v0.5.15.1 之后的匿名版本 6 提交,SHA1 哈希以g61cde1d. 如果您将此命令的输出粘贴到某个*.h文件中,那么您就可以开展业务,并且将发布的软件链接回源代码没有问题。这是做事的首选方式。
If you can't possibly avoid using RCS keywords, you may want to start with this explanation by Lars Hjemli. Basically, $Id$is pretty easy, and you if you're using git archive, you can also use $Format$.
如果您无法避免使用 RCS 关键字,您可能需要从Lars Hjemli 的这个解释开始。基本上,$Id$非常简单,如果您正在使用git archive,您也可以使用$Format$.
But, if you absolutely cannot avoid RCS keywords, the following should get you started:
但是,如果您绝对无法避免 RCS 关键字,则以下内容应该可以帮助您入门:
git config filter.rcs-keyword.clean 'perl -pe "s/\$Date[^\$]*\$/\$Date\$/"'
git config filter.rcs-keyword.smudge 'perl -pe "s/\$Date[^\$]*\$/\$Date: `date`\$/"'
echo '$Date$' > test.html
echo 'test.html filter=rcs-keyword' >> .gitattributes
git add test.html .gitattributes
git commit -m "Experimental RCS keyword support for git"
rm test.html
git checkout test.html
cat test.html
On my system, I get:
在我的系统上,我得到:
$Date: Tue Sep 16 10:15:02 EDT 2008$
If you have trouble getting the shell escapes in the smudgeand cleancommands to work, just write your own Perl scripts for expanding and removing RCS keywords, respectively, and use those scripts as your filter.
如果您在使用smudge和clean命令中的 shell 转义时遇到问题,只需编写您自己的 Perl 脚本来分别扩展和删除 RCS 关键字,并将这些脚本用作您的过滤器。
Note that you reallydon't want to do this for more files than absolutely necessary, or git will lose most of its speed.
请注意,您真的不希望对超过绝对必要的文件执行此操作,否则 git 将失去大部分速度。
回答by Rhialto
Unfortunately, RCS keyword substitution breaks this. For example, using $Date$ would require git checkout to touch every file in the tree when switching branches.
不幸的是,RCS 关键字替换打破了这一点。例如,使用 $Date$ 将需要 git checkout 在切换分支时访问树中的每个文件。
That is not true. $Date$ etc. expand to the value which holds at checkin time. That is much more useful anyway. So it doesn't change on other revisions or branches, unless the file is actually re-checked-in. From the RCS manual:
那不是真的。$Date$ 等扩展到签入时持有的值。无论如何,这更有用。所以它不会在其他修订版或分支上发生变化,除非文件实际上被重新签入。从RCS手册:
$Date$ The date and time the revision was checked in. With -zzone a
numeric time zone offset is appended; otherwise, the date is
UTC.
This also means that the suggested answer above, with the rcs-keyword.smudge filter, is incorrect. It inserts the time/date of the checkout, or whatever it is that causes it to run.
这也意味着上面使用 rcs-keyword.smudge 过滤器的建议答案是不正确的。它插入结帐的时间/日期,或任何导致它运行的内容。
回答by turon
Here is a sample project containing the configuration and filter code needed for adding RCS keyword support to a git project:
这是一个示例项目,其中包含向 git 项目添加 RCS 关键字支持所需的配置和过滤器代码:
https://github.com/turon/git-rcs-keywords
https://github.com/turon/git-rcs-keywords
It's not as simple to setup as one would like, but it seems to work. It uses a smudge/clean filter pair written in perl (similar to what emk's answer described), and yes, it will touch all files with the extensions set in .gitattributes, generally slowing things down a bit.
设置并不像人们想的那么简单,但它似乎有效。它使用了一个用 perl 编写的污迹/清洁过滤器对(类似于 emk 所描述的答案),是的,它会使用 .gitattributes 中设置的扩展名来处理所有文件,通常会减慢速度。
回答by Lily Ballard
You could set the ident attribute on your files, but that would produce strings like
您可以在文件上设置 ident 属性,但这会产生类似的字符串
$Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$
where deadbeef...is the sha1 of the blob corresponding to that file. If you really need that keyword expansion, and you need it in the git repo (as opposed to an exported archive), I think you're going to have to go with the identgitattribute with a custom script that does the expansion for you. The problem with just using a hook is then the file in the working tree wouldn't match the index, and git would think it's been modified.
deadbeef...与该文件对应的 blob 的 sha1在哪里。如果您真的需要该关键字扩展,并且您需要在 git 存储库中使用它(而不是导出的存档),我认为您将不得不使用identgitattribute 以及一个为您进行扩展的自定义脚本。仅使用钩子的问题是工作树中的文件与索引不匹配,并且 git 会认为它已被修改。

