我用git标签弄湿了我的脚,但我之前的背景是Subversion,其中"标签"真的只是副本,而不是"真实"标签...
如果我将标签添加到git仓库,它是应用于所有分支还是仅应用于当前分支?
例如,如果我目前有这些分支(git branch -v
):
* master deadbeef My master head comment
dev baddfeed My def head comment
正如您所见,当前已检出的分支是主分支。现在假设我git tag -a TAGNAME
,TAGNAME
是否仅适用于deadbeef
(主分支)或baddfeed
(dev分支)?
git checkout dev
git checkout TAGNAME
我是否最终结帐baddfeed
或者标签结帐(第二行)将我切换回主分支(标签创建的位置)并给我一个{{1}的结帐}?
(或者第三种选择,我对创建和恢复标签的理解太缺陷或过于简单,答案就像这两个选项中的一个一样简单?)
另外,如果我使用轻量级代码(deadbeef
)而不是带注释的代码,我的问题的答案是否会改变?
答案 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与特定分支(或合并时的分支)相关,因此标记仅与该分支(以及它合并到的任何分支)相关。
可在此处找到更多信息:
答案 2 :(得分:6)
在阅读了问题和你的评论后,我认为让你困惑的基本观点是git(与其他系统相比)在“分支”上的含义。
在git中,git checkout
操作会检查某个特定提交[但请参见脚注1]。它还设置特殊名称HEAD
,以便它引用该特定提交。但是:有两种不同的方式 HEAD
可以指定特定的提交。它可以是:
如果你做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 的人(通常是他们编写的脚本)会因此而感到困惑。因此,除非您先与其他人共享存储库,否则不要移动标记。