代码之家  ›  专栏  ›  技术社区  ›  Joe Casadonte

从cvs迁移到git:$id:$equivalent?

  •  115
  • Joe Casadonte  · 技术社区  · 16 年前

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

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

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

    如果我看到的是40个字符的散列,我就不知道是哪个字符晚了,也不知道晚了多少。如果我不得不手动检查变更日志来了解我的过时程度,我绝对会讨厌它。

    作为一个开发人员,我想把这一礼貌扩展到使用我输出的人身上(也许我在自欺欺人,但让我们把它暂时放在一边)。我不想每次都记得自己增加这个该死的数字,或者一个时间戳之类的东西。这是一个真正的皮塔,我从经验中知道。

    那么我还有什么选择呢?如果我不能得到一个$id:$equivalent,我还能提供我要找的东西吗?

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

    15 回复  |  直到 7 年前
        1
  •  64
  •   Peter Mortensen icecrime    7 年前

    sha只是版本的一种表示(尽管是规范的)。这个 git describe 指挥部提供给其他人,而且做得很好。

    例如,当我跑步时 GIT描述 在我的主分支 Java memcached client 来源,我知道:

    2.2-16-gc0cd61a
    

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

    1. 自2.2以来,此树中总共有16个提交。
    2. 这个 准确的 源树可以显示在其他任何克隆上。

    比如说,你把 version 用源文件(甚至重写所有要分发的内容)来显示该数字。假设打包版本是 2.2-12-g6c4ae7a (不是版本,而是有效版本)。

    现在您可以看到您落后了多少(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.
    
        2
  •  51
  •   Sebastian Pipping    14 年前

    现在已经有了对$id:$的Git支持。为文件启用它 自述文件 将“readme ident”放入 GITS属性 . 支持文件名上的通配符。见 man gitattributes 详情。

        3
  •  31
  •   Peter Mortensen icecrime    7 年前

    这不是OP不合理的要求。

    我的用例是:

    1. 我将Git用于自己的个人代码,因此不与其他人协作。
    2. 我将系统bash脚本保存在那里,它可能会进入 /usr/local/bin 当他们准备好了。

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

    对于那些消极的人,记住还有其他的用例。不是所有人都使用Git进行协作工作,而Git存储库中的文件是他们的“最终”位置。

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

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

    然后把$id$放在文件的某个地方(我喜欢放在shebang之后)。

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

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

    然后您将看到扩展,例如:

    $ head foo.sh
    #!/bin/sh
    
    # $Id: e184834e6757aac77fd0f71344934b1cd774e6d4 $
    

    有一些好消息 How do I enable the ident string for a Git repository? .

        4
  •  23
  •   orip    16 年前

    不确定这会是吉特。到 quote Linus :

    “关键字替换的整个概念完全是愚蠢的。它是 如果你想在实际的内容跟踪之外做一些琐碎的事情 在释放树木时,如焦油球等。

    不过,检查日志非常容易——如果您在跟踪foo.el的稳定分支,您可以看到稳定分支日志中有哪些新提交,而这些新提交不在本地副本中。如果要模拟cvs的内部版本号,可以比较上一次提交的时间戳。

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

        5
  •  20
  •   Community CDub    8 年前

    正如我所写 before :

    使用Bazaar等DSCM工具,不可能自动生成显示合理版本号的ID标签,因为每个人的开发线都可以与其他人不同。所以有人可以引用文件的版本__1.41_157;,但您的版本__1.41__不同。

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

        6
  •  9
  •   Peter Mortensen icecrime    7 年前

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

    我用一个git预提交钩子完成了这项工作,并修改了我的脚本,使其能够自动更新自己。

    我根据已完成的提交数建立版本。这是一个轻微的竞争条件,因为两个人可以同时提交,并且都认为他们提交的是相同的版本号,但是我们在这个项目上没有很多开发人员。

    我的是Ruby,但它不是非常复杂的代码。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 #{$0} | grep '^commit ' | wc -l].to_i + 1
      vers = "1.%0.3d" % commits
    
      t = File.read($0)
      t.gsub!(/^MYVERSION = '(.*)'$/, "MYVERSION = '#{vers}'")
      bak = $0+'.bak'
      File.open(bak,'w') { |f| f.puts t }
      perm = File.stat($0).mode & 0xfff
      File.rename(bak,$0)
      File.chmod(perm,$0)
      exit
    end
    

    然后我有一个命令行选项(-updateVersion),它调用工具的updateVersion。

    最后,我转到git head并在 .git/hooks/pre-commit .

    该脚本只需更改为git目录的头部,并使用 -updateVersion .

    每次我签入时,myversion变量都会根据提交的数量进行更新。

        7
  •  8
  •   Keltia    16 年前

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

        8
  •  8
  •   Peter Mortensen icecrime    7 年前

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

    查看标签很容易。例如,如果有一个标记 v1.1 您可以将该标记签出到这样的分支:

    git checkout -b v1.1
    

    因为它是一个顶级对象,所以您将看到提交的整个历史记录,以及运行diff、进行更改和合并的能力。

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

        9
  •  4
  •   Peter Mortensen icecrime    7 年前

    如果你只是想让人们知道他们离现在有多远,Git可以用几个相当简单的方法通知他们。例如,它们比较主干和主干上最后一次提交的日期。他们可以使用 git cherry 查看您的主干中发生了多少未出现在它们中的提交。

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

    另外,除非你确定他们想要,否则我不会费心向任何人表达礼貌。:)

        10
  •  3
  •   Otto    16 年前

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

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

    % git fetch
    

    然后获取在给定文件上发生的更改的日志, 主人 分支和远程 origin/master .

    % git log master..origin/master foo.el
    

    这将提供自上次合并以来在远程存储库中发生的所有提交的日志消息。 起源/大师 进入你 主人 .

    如果您只想计算更改的数量,请将其传送到 wc . 说,像这样:

    % git rev-list master..origin/master foo.el | wc -l
    
        11
  •  3
  •   Peter Mortensen icecrime    7 年前

    对于单个文件项目来说,rcs id是很好的,但是对于任何其他项目,$id$都没有提到该项目(除非您强制对一个虚拟版本文件执行虚拟签入)。

    仍然有人可能对如何在每个文件级别或提交级别上获取$author$、$date$、$revision$、$rcsfile$等等价项感兴趣(如何将它们放在某些关键字所在的位置是另一个问题)。我没有关于这些问题的答案,但是看到了更新这些问题的需求,特别是当文件(现在在Git中)来自与rcs兼容的系统(cvs)时。

    如果源是与任何Git存储库分开分发的(这也是我要做的),那么这些关键字可能很有趣。我的解决方案如下:

    每个项目都有自己的目录,在项目根目录中,我有一个名为 .version 哪个内容描述当前版本(导出源时将使用的名称)。

    在为下一个版本工作时,脚本将提取 版本 数字,一些Git版本描述符(如 git describe )和单调的内建数 .build (加上主机和日期)到一个自动生成的源文件,该文件链接到最终程序,这样您就可以从哪个源以及何时构建它。

    我在不同的分支中开发新特性,我首先要做的是添加 n (用于“下一步”)到 版本 字符串(源自同一根的多个分支将使用同一个临时 版本 号码)。在发布之前,我决定合并哪些分支(希望所有分支都有相同的分支) 版本 )在提交合并之前,我更新 版本 到下一个数字(主要或次要更新,取决于合并的功能)。

        12
  •  1
  •   Agustí Sánchez    9 年前

    我同意那些认为令牌替换属于构建工具而不是版本控制工具的人。

    您应该有一些自动化的发布工具来设置发布被标记时源代码中的版本ID。

        13
  •  0
  •   Peter Mortensen icecrime    7 年前

    既然你使用emacs,你可能会很幸运的:)

    我是偶然碰到这个问题的,也是偶然碰到的。 Lively 几天前,一个Emacs包允许在您的文档中有活跃的EmacsLisp片段。我没试过说实话,但读到这篇文章时,我想到了。

        14
  •  0
  •   Peter Mortensen icecrime    7 年前

    我也来自SCC、RCS和CVS( %W% %G% %U% )

    我也遇到过类似的挑战。我想知道运行代码的任何系统上的代码版本。系统可能连接到任何网络,也可能不连接到任何网络。系统可能安装了Git,也可能没有安装Git。系统上可能安装了GitHub存储库,也可能没有安装。

    对于几种类型的代码(.sh,.go,.yml,.xml等),我需要相同的解决方案。我希望任何不了解Git或Github的人都能回答这个问题。 “您运行的是哪个版本?”

    所以,我写了一些关于git命令的包装器。我用它来标记一个带有版本号和一些信息的文件。它解决了我的挑战。这可能对你有帮助。

    https://github.com/BradleyA/markit

    git clone https://github.com/BradleyA/markit
    cd markit
    
        15
  •  0
  •   Nagev    7 年前

    要将扩展应用于存储库中所有子目录中的所有文件,请添加 .gitattributes 文件到存储库中的顶级目录(即通常将 .gitignore 文件)包含:

    * ident
    

    要看到这个效果,您需要首先对文件进行有效的签出,例如以任何方式删除或编辑它们。然后用以下方法恢复它们:

    git checkout .
    

    你应该看到 $Id$ 替换为如下内容:

    $Id: ea701b0bb744c90c620f315e2438bc6b764cdb87 $
    

    man gitattributes :

    识别的

    当为路径设置属性ident时,git将替换路径中的$id$ 具有$id:的blob对象,后跟40个字符的十六进制blob对象 姓名,结帐时在后面写上美元符号。开始的任何字节序列 签入时,WorkTree文件中以$结尾的$id:将替换为$id$。

    每次提交新版本的文件时,此ID都将更改。

    推荐文章