17

我被 git 标签弄湿了,但我以前的背景是在 Subversion 中,“标签”实际上只是副本,而不是“真实”标签......

如果我向 git repo 添加标签,它是应用于所有分支还是仅应用于当前分支?

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

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

如您所见,当前签出的分支是 master。现在假设 Igit tag -a TAGNAME是否也TAGNAME仅适用于deadbeef(master 分支) 或baddfeed(dev 分支)?

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

git checkout dev
git checkout TAGNAME

然后我是否baddfeed会结帐或者标签结帐(第二行)会将我切换回主分支(创建标签的位置)并给我结帐deadbeef?(或者第三个选项,我对创建和恢复标签的理解是否过于有缺陷或过于简单,以至于答案不能像这两个选项之一那样简单?)

另外,如果我使用轻量级标签 ( git tag TAGNAME) 而不是带注释的标签,我的问题的答案是否会改变?

4

3 回答 3

22

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

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

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

如果您 checkout myTag,您将处于G示例的提交中。您不能在不同的分支上创建具有相同名称的标签。如果你这样做,你将移动标签。

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

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

于 2013-08-06T19:21:59.703 回答
8

为了简单起见:

如果我向 git repo 添加标签,它是应用于所有分支还是仅应用于当前分支?

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

更多信息可以在这里找到:

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

于 2013-08-06T20:41:33.280 回答
7

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

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

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

如果你这样做了,git 会设置第二种,通常的情况。如果你那么你会发现它包含文字字符串,后跟[2]。这就是“在分支上”的含义:您已经检查了分支名称所指的提交,但也是一个“符号引用”。如果您进行新的更改并提交它们,git 将进行新的提交,然后“剥离”分支标签便笺并将其粘贴到您刚刚添加的新提交上。这会将分支“移动”到新添加的提示,而您“仍在分支上”。git checkout branchnamecat .git/refs/HEADref:refs/heads/branchnameHEAD

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

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


脚注:

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

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

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

于 2013-08-06T22:02:51.193 回答