git标签主要用作一种别名吗?

时间:2014-12-24 09:36:46

标签: git alias git-tag

到目前为止,我知道我可以使用git tag -a tag_name -m "tag message"制作带注释的标签。

然后使用git show tag_name查看特定标记的更改信息。

实际上,此标记已绑定到提交。所以我真正看到的是那次提交的变化。

那么,git tag主要用作别名还是提醒,所以我们不需要记住那些不人道的HEADS?

或者到目前为止我还不知道标签的一些神奇功能?

2 个答案:

答案 0 :(得分:6)

已经有了一个非常好的答案,但我想添加一个不同方向的答案。

从某个重要方面来看,问题的回答("标记是否为别名")是,但这可能会产生误导,因为在git中,所有名称充当别名(在有意义的情况下)。

更具体地说,"真实姓名"任何git对象都是它的SHA-1 ID,当你提​​到"那些不人道的HEADS"时,你可能会提到它。每个SHA-1都是一个40个字符的字符串,如c18b86734113ee2aeb0e140c922c8fbd4accc860。标记是查找此类ID的一种方式,但分支名称如masterdevel也是如此,HEADHEAD^,{{1}等字符串也是如此等等。

事实上,git有一个相当丰富的语法系统,用于将名称转换为SHA-1 ID,在the gitrevisions page中有记录。例如,要查找包含字符串" bug1234"的提交,您可以编写master~3。 (冒号表示特殊情况,斜杠指定搜索,文本的其余部分实际上是一个完整的正则表达式。)

从语义上讲,使用分支名称使标记名称不同的是,分支名称​​期望随着时间的推移解析为不同的提交ID,实际上,在&时进行新的提交#34;上&#34;分支(如,git show :/bug1234表示git status自动更新分支名称到ID映射。 1 标记名称,由相比之下,预计会像这样移动,而git不会轻易移动它。 (人们可以强行移动&#34;标记,代价是可能会混淆已经保存名称到ID映射的其他用户:其他用户很可能继续使用旧ID。)< / p>

正如the other answer所述,有两种形式的标签,&#34;轻量级&#34; (直接指向提交 2 )和&#34;注释&#34; (它实际上是一对,带有指向实际标记对象的轻量级标记,然后存储一些数据,包括另一个指针;第二个指针指向提交)。

您可以使用on branch master命令将修订说明符转换为原始SHA-1 ID。此命令具有许多其他功能,但其中一个部分只是将参数删除到修订语法处理程序中。命名SHA-1的原始SHA-1名称; 3 给出分支或标记名称,以获取分支或标记指向的内容。

这最后是轻量级标签和带注释标签之间的差异变得显着的地方。如果您有注释标记git rev-parse指向提交,则命令annotag将获取标记对象的SHA-1 ID,而不是提交本身。如果您有一个指向同一提交的轻量级标记git rev-parse annotaglightag将为您提供提交的SHA-1 ID。事实上,这种不同的行为通常是你想要的 - 但如果没有,它很容易处理,因为在所有其他花哨的语法中,有一个后缀语法,让你指定你必须获取提交对象:git rev-parse lightag表示将git rev-parse v1.2^{commit}字符串转换为提交。如果v1.2是带注释的标记,git将找到它指向的提交。 4

除了&#34;剥离&#34;的特殊语法。标签(见脚注4),需要提交的git命令会自动进行剥离。例如,给定带注释的标记名称,v1.2将显示标记标记所指向的对象。

总而言之,分支名称和标记名称都是别名,但它们的用途不同:标记是&#34;固定的&#34;别名(对于一个特定的,不变的SHA-1),而分支名称是&#34;变量&#34;别名(某种历史中最新的SHA-1)。


1 事实上,这真的是在分支机构&#34;&#34; 表示:进行新提交不仅会进行新提交,还会更新branch-name-to-commit-ID映射。如果您专门使用git show进入&#34;分离的HEAD&#34;模式,或者如果您签出标签ID或以其他方式获得&#34; off&#34;分支到这个&#34;分离的HEAD&#34;模式,你仍然可以进行新的提交。每次执行此操作时,新的提交ID都存储在--detach文件中,而不是存储在分支文件中。一旦你签出了不同的分支或提交,HEAD文件被分支名称或原始提交ID覆盖,任何这样的新提交实际上只是暂时的,除非你给他们一个分支或标签名称。这就是HEAD命令在内部工作的方式,例如:它离开分支,将提交复制为新的临时提交,当它完成复制最后一次提交时,它会重新洗牌分支名称以便新提交不再是临时性的,它已成为临时的提交链。

2 实际上,标签可以指向任何git对象。通常,轻量级标记应指向提交,注释标记的轻量级条目必须(有意义)指向带注释的标记对象。但是,一个带注释的标记对象可以指向另一个带注释的标记对象,依此类推,并且它可能 - 甚至可用于特殊目的 - 使引用(不一定是标记)直接指向树或blob对象。

3 实际上,如果您将一个40个字符的SHA-1字符串提供给rebase,则该ID不需要存储在存储库中。但是,如果使用缩写形式,git rev-parse将查找对象,如果ID丢失或不明确则失败,或者如果没有,则查找完整的40个字符的形式。

4 请注意,这假定标记指向提交,可能在遵循一定数量的中间注释标记之后。稍微不同的语法rev-parse告诉git 如果 rev^{} 参数是带注释的标记,它应该跟随该标记到其对象,如果该对象也是一个标记,它应该再次跟随,并重复,直到它到达非标记。这个过程也被称为&#34;剥离&#34;。

另请注意,某些命令解释程序会特别处理大括号,因此在某些情况下,您可能需要使用引号来保护其中一些字符串。

答案 1 :(得分:3)

实际上git知道两种标签:

  • “普通”轻量级标签,只不过是提交的另一个名称和
  • 带注释标签,其中包含其他信息并存储为单独的对象。

每当您使用git tag -a时,您都会创建一个带注释的标签。您通常将其用于发布。它将存储创建标签的人员,完成后,您可以添加消息,甚至可以签署您的标签。所有这些信息都没有轻量级标签。

有关详细信息,请查看git help tag