从 CVS 迁移到 Git:相当于 $Id$ 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/384108/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:02:45  来源:igfitidea点击:

Moving from CVS to Git: $Id$ equivalent?

gitversion-controlcvskeyword-substitution

提问by Joe Casadonte

I read through a bunch of questions asking about simple source code control tools and Git seemed like a reasonable choice. I have it up and running, and it works well so far. One aspect that I like about CVS is the automatic incrementation of a version number.

我通读了一堆关于简单源代码控制工具的问题,Git 似乎是一个合理的选择。我已经启动并运行它,到目前为止它运行良好。我喜欢 CVS 的一个方面是版本号的自动递增。

I understand that this makes less sense in a distributed repository, but as a developer, I want/need something like this. Let me explain why:

我知道这在分布式存储库中意义不大,但作为开发人员,我想要/需要这样的东西。让我解释一下原因:

I use Emacs. Periodically I go through and look for new versions of the Lisp source files for third-party packages. Say I've got a file, foo.el, which, according to the header, is version 1.3; if I look up the latest version and see it's 1.143 or 2.6 or whatever, I know I'm pretty far behind.

我使用 Emacs。我会定期浏览并寻找第三方包的 Lisp 源文件的新版本。假设我有一个文件 foo.el,根据标题,它是 1.3 版;如果我查看最新版本并看到它是 1.143 或 2.6 或其他版本,我知道我远远落后了。

If instead I see a couple of 40-character hashes, I won't know which is later or get any idea of how much later it is. I would absolutely hate it if I had to manually check ChangeLogs just to get an idea of how out of date I am.

相反,如果我看到几个 40 个字符的哈希,我将不知道哪个更晚,也不知道它晚了多久。如果我不得不手动检查 ChangeLogs 只是为了了解我是如何过时的,我绝对会讨厌它。

As a developer, I want to extend this courtesy, as I see it, to the people that use my output (and maybe I'm kidding myself that anyone is, but let's leave that aside for a moment). I don't want to have to remember to increment the damn number myself every time, or a timestamp or something like that. That's a real PITA, and I know that from experience.

作为一名开发人员,我想将这种礼貌扩展到使用我的输出的人身上(也许我在开玩笑说任何人都是这样,但让我们暂时搁置一下)。我不想每次都记得自己增加该死的数字,或者时间戳或类似的东西。那是真正的 PITA,我从经验中知道这一点。

So what alternatives do I have? If I can't get an $Id:$ equivalent, how else can I provide what I'm looking for?

那么我有哪些选择呢?如果我无法获得 $Id:$ 等价物,我还能如何提供我正在寻找的信息?

I should mention that my expectation is that the end user will NOT have Git installed and even if they do, will not have a local repository (indeed, I expect not to make it available that way).

我应该提到,我的期望是最终用户不会安装 Git,即使他们安装了,也不会拥有本地存储库(实际上,我希望不会以这种方式提供它)。

采纳答案by Dustin

The SHA is just one representation of a version (albeit canonical). The git describecommand offers others and does so quite well.

SHA 只是版本的一种表示(尽管是规范的)。该git describe命令提供了其他命令,并且做得很好。

For example, when I run git describein my master branch of my Java memcached clientsource, I get this:

例如,当我git describeJava memcached 客户端源的master 分支中运行时,我得到以下信息:

2.2-16-gc0cd61a

That says two important things:

这说明了两件重要的事情:

  1. There have been exactly 16 commits in this tree since 2.2
  2. The exactsource tree can be displayed on anyone else's clone.
  1. 自 2.2 以来,这棵树中正好有 16 次提交
  2. 精确的源树可以在任何人的克隆显示。

Let's say, for example, you packaged a versionfile with the source (or even rewrote all the content for distribution) to show that number. Let's say that packaged version was 2.2-12-g6c4ae7a(not a release, but a valid version).

比方说,例如,您将version文件与源打包在一起(甚至重写了所有内容以进行分发)以显示该编号。假设打包版本是2.2-12-g6c4ae7a(不是发行版,而是有效版本)。

You can now see exactly how far behind you are (4 commits), andyou can see exactly which 4 commits:

您现在可以准确地看到落后了多远(4 次提交),并且可以准确地看到是哪 4 次提交:

# The RHS of the .. can be origin/master or empty, or whatever you want.
% git log --pretty=format:"%h %an %s" 2.2-12-g6c4ae7a..2.2-16-gc0cd61a
c0cd61a Dustin Sallings More tries to get a timeout.
8c489ff Dustin Sallings Made the timeout test run on every protocol on every bui
fb326d5 Dustin Sallings Added a test for bug 35.
fba04e9 Valeri Felberg Support passing an expiration date into CAS operations.

回答by Sebastian Pipping

By now there is support for $Id:$ in Git. To enable it for file READMEyou would put "README ident" into .gitattributes. Wildcards on file names are supported. See man gitattributesfor details.

到目前为止,Git 支持 $Id:$。要为文件README启用它,您需要将“README ident”放入.gitattributes。支持文件名上的通配符。有关详细信息,请参阅man gitattributes

回答by Imran-UK

This isn't an unreasonable request from the OP.

这不是来自 OP 的无理要求。

My use-case is:

我的用例是:

  1. I use Git for my own personal code, therefore no collaboration with others.
  2. I keep system Bash scripts in there which might go into /usr/local/binwhen they are ready.
  1. 我将 Git 用于我自己的个人代码,因此不与他人合作。
  2. 我将系统 Bash 脚本保存在那里,/usr/local/bin当它们准备好时可能会进入。

I use three separate machines with the same Git repository on it. It would be nice to know what "version" of the file I have currently in /usr/local/binwithout having to do a manual "diff -u <repo version> <version in /usr/local/bin>".

我使用三台独立的机器,上面有相同的 Git 存储库。/usr/local/bin无需手动执行“diff -u <repo version> <version in /usr/local/bin>” ,就可以知道我当前所在文件的“版本”。

To those of you being negative, remember there are other use cases out there. Not everyone uses Git for collaborative work with the files in the Git repository being their "final" location.

对于那些消极的人,请记住还有其他用例。并非每个人都使用 Git 进行协作,将 Git 存储库中的文件作为他们的“最终”位置。

Anyway, the way I did it was to create an attributes file in the repository like this:

无论如何,我这样做的方法是在存储库中创建一个属性文件,如下所示:

cat .git/info/attributes
# see man gitattributes
*.sh ident
*.pl ident
*.cgi ident

Then put $Id$ somewhere in the file (I like to put it after the shebang).

然后将 $Id$ 放在文件中的某个位置(我喜欢把它放在 shebang 之后)。

The commit. Note that this doesn't automatically do the expansion like I expected. You have to re-co the file, for example,

提交。请注意,这不会像我预期的那样自动进行扩展。您必须重新制作文件,例如,

git commit foo.sh
rm foo.sh
git co foo.sh

And then you will see the expansion, for example:

然后你会看到扩展,例如:

$ head foo.sh
#!/bin/sh

# $Id: e184834e6757aac77fd0f71344934b1cd774e6d4 $

Some good information is in How do I enable the ident string for a Git repository?.

一些好的信息是如何启用一个Git仓库的IDENT字符串?.

回答by orip

Not sure this will ever be in Git. To quote Linus:

不确定这是否会出现在 Git 中。要引用莱纳斯

"The whole notion of keyword substitution is just totally idiotic. It's trivial to do "outside" of the actual content tracking, if you want to have it when doing release trees as tar-balls etc."

“关键字替换的整个概念完全是愚蠢的。如果您想在将发布树作为 tar-ball 等进行发布时使用它,那么在实际内容跟踪之外进行“外部”是微不足道的。”

It's pretty easy to check the log, though - if you're tracking foo.el's stable branch, you can see what new commits are in the stable branch's log that aren't in your local copy. If you want to simulate CVS's internal version number, you can compare the timestamp of the last commit.

但是,检查日志非常容易 - 如果您正在跟踪 foo.el 的稳定分支,您可以看到稳定分支日志中没有本地副本中的新提交。如果要模拟 CVS 的内部版本号,可以比较上次提交的时间戳。

Edit: you should write or use someone else's scripts for this, of course, not do this manually.

编辑:您应该为此编写或使用其他人的脚本,当然,不要手动执行此操作。

回答by Bombe

As I've written before:

正如我写之前

Having automatically generated Id tags that show a sensible version number is impossible to do with DSCM tools like Bazaar because everybody's line of development can be different from all others. So somebody could refer to version “1.41” of a file but your version “1.41” of that file is different.

Basically, $Id$ does not make any sense with Bazaar, Git, and other distributed source code management tools.

使用 Bazaar 等 DSCM 工具无法自动生成显示合理版本号的 Id 标签,因为每个人的开发路线都可能与其他人不同。因此,有人可以引用文件的“1.41”版本,但该文件的“1.41”版本是不同的。

基本上,$Id$ 对 Bazaar、Git 和其他分布式源代码管理工具没有任何意义。

回答by David Ljung Madison Stellar

I had the same problem. I needed to have a version that was simpler than a hash string and available for people using the tool without needing to connect to the repository.

我有同样的问题。我需要一个比哈希字符串更简单的版本,并且可供使用该工具的人使用而无需连接到存储库。

I did it with a Git pre-commit hook and changed my script to be able to automatically update itself.

我使用 Git 预提交钩子完成了它,并更改了我的脚本以使其能够自动更新。

I base the version off of the number of commits done. This is a slight race condition because two people could commit at the same time and both think they are committing the same version number, but we don't have many developers on this project.

我根据完成的提交数量来确定版本。这是一个轻微的竞争条件,因为两个人可以同时提交,并且都认为他们提交的是相同的版本号,但我们没有多少开发人员参与这个项目。

As an example, I have a script that I checkin that is in Ruby, and I add this code to it - it's pretty simple code so it's easy to port to different languages if you are checking in something in a different language (though obviously this won't easily work with non-runnable checkins such as text files). I've added:

举个例子,我有一个脚本,我在 Ruby 中签入,我向它添加了这个代码 - 这是非常简单的代码,所以如果你用不同的语言签入一些东西,很容易移植到不同的语言(尽管显然这不会轻易与不可运行的签入(例如文本文件)一起使用)。我已经添加:

MYVERSION = '1.090'
## Call script to do updateVersion from .git/hooks/pre-commit
def updateVersion
  # We add 1 because the next commit is probably one more - though this is a race
  commits = %x[git log #{
git checkout -b v1.1
} | grep '^commit ' | wc -l].to_i + 1 vers = "1.%0.3d" % commits t = File.read(
% git fetch
) t.gsub!(/^MYVERSION = '(.*)'$/, "MYVERSION = '#{vers}'") bak =
% git log master..origin/master foo.el
+'.bak' File.open(bak,'w') { |f| f.puts t } perm = File.stat(
% git rev-list master..origin/master foo.el | wc -l
).mode & 0xfff File.rename(bak,##代码##) File.chmod(perm,##代码##) exit end

And then I add a command-line option (-updateVersion) to the script so if I call it as "tool -updateVersion" then it just calls updateVersion for the tool which modifies the "MYVERSION" value in itself and then exits (you could have it also update other files if they are opened as well if you wanted).

然后我在脚本中添加了一个命令行选项 (-updateVersion),所以如果我将它称为“工具 -updateVersion”,那么它只会为工具调用 updateVersion 来修改“MYVERSION”本身的值然后退出(你可以如果您愿意,还可以更新其他文件(如果它们也被打开)。

Once that's setup, I go to the Git head and create an executable one-line bash script in .git/hooks/pre-commit.

设置完成后,我将转到 Git 头并在 .git 文件中创建一个可执行的单行 bash 脚本.git/hooks/pre-commit

The script simply changes to the head of the Git directory and calls my script with -updateVersion.

该脚本只是更改为 Git 目录的头部并使用-updateVersion.

Every time I check in the pre-commit script is run which runs my script with -updateVersion, and then the MYVERSION variable is updated based on what the number of commits will be. Magic!

每次我检查预提交脚本时都会运行它,它使用 -updateVersion 运行我的脚本,然后根据提交的数量更新 MYVERSION 变量。魔法!

回答by Abizern

Something that is done with Git repositories is to use the tagobject. This can be used to tag a commit with any kind of string and can be used to mark versions. You can see that tags in a repository with the git tagcommand, which returns all the tags.

使用 Git 存储库所做的事情是使用tag对象。这可用于用任何类型的字符串标记提交,并可用于标记版本。您可以使用git tag命令查看存储库中的标签,该命令返回所有标签。

It's easy to check out a tag. For example, if there is a tag v1.1you can check that tag out to a branch like this:

签出标签很容易。例如,如果有一个标签,v1.1您可以将该标签检出到一个分支,如下所示:

##代码##

As it's a top level object, you'll see the whole history to that commit, as well as be able to run diffs, make changes, and merges.

由于它是顶级对象,因此您将看到该提交的整个历史记录,并且能够运行差异、进行更改和合并。

Not only that, but a tag persists, even if the branch that it was on has been deleted without being merged back into the main line.

不仅如此,一个标签仍然存在,即使它所在的分支已被删除而没有合并回主线。

回答by Keltia

If having $Keywords$ is essential for you, then maybe you could try to look at Mercurialinstead? It has a hgkeyword extension that implement what you want. Mercurial is interesting as a DVCS anyway.

如果拥有 $Keywords$ 对您来说必不可少,那么也许您可以尝试查看Mercurial?它有一个 hgkeyword 扩展来实现你想要的。无论如何,作为 DVCS,Mercurial 很有趣。

回答by Otto

If I understand correctly, essentially, you want to know how many commits have happened on a given file since you last updated.

如果我理解正确,本质上,您想知道自上次更新以来在给定文件上发生了多少次提交。

First get the changes in the remote origin, but don't merge them into your masterbranch:

首先获取远程源中的更改,但不要将它们合并到您的master分支中:

##代码##

Then get a log of the changes that have happened on a given file between your masterbranch and the remote origin/master.

然后获取在您的master分支和远程之间的给定文件上发生的更改的日志origin/master

##代码##

This gives you the log messages of all the commits that have happened in the remote repository since you last merged origin/masterinto your master.

这为您提供了自您上次合并origin/master到您的master.

If you just want a count of the changes, pipe it to wc. Say, like this:

如果您只想对更改进行计数,请将其通过管道传输到wc. 说,像这样:

##代码##

回答by skiphoppy

If you're just wanting people to be able to get an idea how far out of date they are, Git can inform them of that in several fairly easy ways. They compare the dates of the last commit on their trunk and your trunk, for example. They can use git cherryto see how many commits have occurred in your trunk that are not present in theirs.

如果您只是希望人们能够知道他们已经过时了多远,Git 可以通过几种相当简单的方式通知他们。例如,他们比较他们的主干和你的主干上最后一次提交的日期。他们可以git cherry用来查看您的主干中发生了多少他们的主干中不存在的提交。

If that's all you want this for, I'd look for a way to provide it without a version number.

如果这就是你想要的,我会寻找一种没有版本号的方法来提供它。

Also, I wouldn't bother extending the courtesy to anyone unless you're sure they want it. :)

另外,除非您确定他们想要,否则我不会向任何人提供礼貌。:)