我正在浏览一些git内部,并且看到了标签以及它们如何在内部存储。在Git SCM site我找到了以下内容:
签出标签
你无法真正签出Git中的标签,因为它们无法移动 周围。如果你想在你的版本中放置一个版本的存储库 工作目录看起来像一个特定的标签,你可以创建一个新的 使用git checkout -b [branchname] [tagname]分支到特定标签:
git checkout -b version2 v2.0.0
切换到新分支'版本2'
当然,如果你这样做并提交,你的version2分支将是 与v2.0.0标签略有不同,因为它会向前移动 随着你的新变化,所以要小心。
我有以下疑问:
HEAD
指向标记指向的提交吗? 谢谢。
修改
我指的是HEAD和标签指向不同提交的情况。
答案 0 :(得分:4)
为什么我们不能查看标签?
我们可以!
我们不能遍历Git TAG以使HEAD指向标记所指向的提交吗?
是的,我们可以做到这一点(但严格来说,我们甚至不需要太多,如果有任何遍历:提交是快照,所以一旦我们到达正确的,我们就完成了,标签通常需要零或达到提交的一个中间步骤。)
HEAD
文件的更典型状态 - 它是名为.git
的{{1}}中的实际文件 - 是它包含分支的名称 ,而不是提交的 ID 。这种模式没有太多的正式名称,但我将其称为“在分支上”,将其与其他模式进行对比。
HEAD
直接指向某个提交(通过包含其哈希ID)时获得的模式是as CodeWizard mentioned in a comment,称为“分离的HEAD”。由于.git/HEAD
不再包含分支的名称,因此我们现在位于 no 分支上 - 或者等效地,在某种未命名的分支上,我们可以使用.git/HEAD
用于命名的符号(自Git版本1.8.5开始),或拼写出单词@
。当然HEAD
是个好名字;只是当我们再次运行HEAD
时,Git将覆盖.git/HEAD
文件的内容,然后我们将不再将哈希ID存储在任何地方。
我们可以创建一个新的提交,然后指向tag指向的提交作为父提交吗?
英语在这里有点含糊不清,但我认为图表更清楚答案是肯定的:
git checkout master
此处,提交 initially: on branch `master` with commit `H` as the current commit
...--F--G <-- tag: v2.0.0
\
H <-- master (HEAD)
指回提交H
;提交G
指向提交G
;等等。名为F
的分支指向提交master
,标记名H
指向提交v2.0.0
(直接,如果它是轻量级标记,或通过一个带注释的标签对象,如果它是带注释的标签)。
G
After `git checkout v2.0.0`:
...--F--G <-- HEAD, tag: v2.0.0
\
H <-- master
文件现在包含提交.git/HEAD
的哈希ID。
G
新提交If we make a new commit now:
I <-- HEAD
/
...--F--G <-- tag: v2.0.0
\
H <-- master
已提交I
作为其父级,如您所建议的那样。 G
文件现在包含提交.git/HEAD
的哈希ID。
据说如果我们从标签创建一个新的分支并提交,它会略有不同。他们在谈论什么不同?新的提交(假设没有任何改变)是否会将标记的提交称为其父级,其他所有内容(树和blob)保持不变?
提交内容将是相同的,但提交图的绘图会稍微改变一下。这是新的图形绘制,从相同的起点开始,但使用I
作为中间步骤。
git checkout -b version2 v2.0.0
请注意,在这种情况下 - 我们在“分支”上的一个名为 initially: on branch `master` with commit `H` as the current commit
...--F--G <-- tag: v2.0.0
\
H <-- master (HEAD)
After `git checkout -b version2 v2.0.0`:
...--F--G <-- version2 (HEAD), tag: v2.0.0
\
H <-- master
If we make a new commit now:
I <-- version2 (HEAD)
/
...--F--G <-- tag: v2.0.0
\
H <-- master
- 的分支名称随着我们进行新提交而移动 。当我们不在任何分支上时,在“分离的HEAD”模式下,新提交只更新(存储在其中的提交哈希ID)version2
。但是当.git/HEAD
包含分支的名称时,那些新提交会更新该分支。 .git/HEAD
文件本身只是继续包含分支的名称。
事实上,这就是“在一个分支上”意味着什么:只要.git/HEAD
包含分支的名称,各种操作 - 特别包括进行新的提交和使用.git/HEAD
- 更改分支名称记住的哈希ID ,而不是更改git reset
本身。只要.git/HEAD
包含提交的哈希ID ,这些相同的操作就会更新.git/HEAD
本身。
.git/HEAD
命令通常会更新git checkout
的内容,并且是可以更改.git/HEAD
中存储的分支名称的少数命令之一。 (我在这里说“通常”,因为.git/HEAD
有点kitchen-sink command,有各种模式做奇怪的事情,因为它们与它通常做的主要事情密切相关。)具体来说,如果你在一个分支上,git checkout
可以把你带到不同的分支;如果你不在任何一个分支上,git checkout
可以让你进入一个分支;如果您使用git checkout
或标签名称或类似名称,--detach
可以使您进入分离的HEAD模式;如果您不在任何分支上,git checkout
可以更改指向哪个提交git checkout
。
(HEAD
命令可以执行其中的一些操作,但它不会带你上下任何分支。就像git reset
一样,它有点“厨房下沉”:它有很多东西它可以做到,如果没有很多单词和几个图表,很难很好地描述这些!)