git标签适用于所有分支吗?

时间:2013-08-06 18:49:58

标签: git branch git-branch git-tag

我用git标签弄湿了我的脚,但我之前的背景是Subversion,其中"标签"真的只是副本,而不是"真实"标签...

如果我将标签添加到git仓库,它是应用于所有分支还是仅应用于当前分支?

例如,如果我目前有这些分支(git branch -v):

* master deadbeef My master head comment
  dev    baddfeed My def head comment

正如您所见,当前已检出的分支是主分支。现在假设我git tag -a TAGNAMETAGNAME是否仅适用于deadbeef(主分支)或baddfeed(dev分支)?

例如,假设我在签出标签之前切换到dev分支(即,不是创建标签的分支):

git checkout dev
git checkout TAGNAME

我是否最终结帐baddfeed或者标签结帐(第二行)将我切换回主分支(标签创建的位置)并给我一个{{1}的结帐}? (或者第三种选择,我对创建和恢复标签的理解太缺陷或过于简单,答案就像这两个选项中的一个一样简单?)

另外,如果我使用轻量级代码(deadbeef)而不是带注释的代码,我的问题的答案是否会改变?

3 个答案:

答案 0 :(得分:18)

假设你在分支myBranch。然后创建一个名为myTag

的标记
-----A-----B-----C-----D-----H-------I-----> master
                       \
                        \
                         \---E----F-----G-----> myBranch
                                        |
                                        myTag

标记仅位于myBranch分支的提交对象上。我也使用过CVS,它也标记了修订,而不是所有分支(但在CVS分支中是特殊标记)。我不认为。

如果您结帐myTag,您将进入示例的提交G。您不能在不同分支上创建具有相同名称的标记。如果你这样做,你将移动标签。

与此相关的带注释标签没有区别。

注意:签出标签时,最终会出现“分离的HEAD”模式。除非您从签出的标签开始创建另一个分支,否则您的更改将会丢失。

答案 1 :(得分:6)

简化:

  

如果我将标签添加到git仓库,它是应用于所有分支还是仅应用于当前分支?

在Git中,标签只是提交ID的别名。添加标记时,Git只是将标记名称(标记字符串)映射到给定的提交ID。由于提交ID与特定分支(或合并时的分支)相关,因此标记仅与该分支(以及它合并到的任何分支)相关。

可在此处找到更多信息:

http://git-scm.com/book/en/Git-Basics-Tagging#Creating-Tags

答案 2 :(得分:6)

在阅读了问题和你的评论后,我认为让你困惑的基本观点是git(与其他系统相比)在“分支”上的含义。

在git中,git checkout操作会检查某个特定提交[但请参见脚注1]。它还设置特殊名称HEAD,以便它引用该特定提交。但是:有两种不同的方式 HEAD可以指定特定的提交。它可以是:

  • 按ID(这是 -usual情况)或
  • 通过间接引用分支名称(这是更常见的情况)。

如果你做git checkout branchname,git会设置第二个通常情况。如果您cat .git/refs/HEAD,则会发现它包含文字字符串ref:,后跟refs/heads/branchname [2]。这就是“在分支上”意味着:你已经检查了分支名称引用的提交,但是HEAD是一个“符号引用”。如果您进行新的更改并提交它们,git将进行新的提交,然后“剥离”分支标签粘滞便笺并将其粘贴到刚刚添加的新提交中。这会“移动分支”到新添加的提示,并且您“仍然在分支上”。

另一方面,如果你做git checkout tagname,git会设置第一个不寻常的情况。如果您通过SHA-1 ID(那些ea56709...样式字符串)签出,它也会这样做。在这种情况下,HEAD的文件中只包含文字SHA-1 ID。在这种状态下,如果你进行新的提交,它会像往常一样添加,但是没有粘滞便笺更改来移动分支标签。你不是“在树枝上”; HEAD不是“符号参考”。

就实际标签本身而言,它们只是提交的名称。但等等,是不是分支名称是什么?是!分支名称和标记名称之间的区别在于分支名称​​预期要移动,git将在“分支”情况下自动移动它。标签名称“预计会移动”[3]并且永远不会自动移动。


脚注:

[1]只是为了混淆事物(或者因为git的用户界面是“邪恶的”,正如有人会说的那样:-))有些情况git checkout不会改变HEAD,特别是你要它查看特定的路径名​​。

[2]在非常旧版本的git中,git使用了符号链接而不是ref: ...。链接的目标是分支ID文件,例如refs/heads/master或其他什么,因此打开和读取文件获得了提交ID,您必须使用lstat来检测“在分支上” 。这在Windows上不起作用,并且排除了“打包”引用(.git/packed-refs),因此改为使用ref:

[3]短语“预期”和“未预期”应提示您提出:预期由谁? Git本身可以使用git用户移动标签,而使用git 的人(通常是他们编写的脚本)会因此而感到困惑。因此,除非您先与其他人共享存储库,否则不要移动标记。