Git - 在标签之间切换

Git - Switching between tags

我在尝试检查同一提交的不同标签时遇到问题。

这成为我检查分离头位置的应用程序中的一个问题。

我相信这是因为提交被标记为 4.1 和 4.1.1 但我需要 head 在我从 4.1 检出 tags/4.1 时明确地说 "HEAD detached at 4.1" .1 标签不显示相同的 "HEAD detached at 4.1.1" 文本。

无法从 4.1 更新分离头 -> 4.1.1

无法从 4.1.1 更新分离头 -> 4.1

在上次签出时我无法从 4.1 切换到 4.1.1,可能是因为 HEAD 已经在提交中,在这种情况下是否有某种方式强制 "HEAD detached at N" 而不是签出 master 分支然后查看标签。

因为这应该在生产中使用,当可能有一些用户在线时,我希望结帐尽可能顺畅和清晰(头部分离)可能。

TL;DR:显然,您必须作弊。我不建议这样做,但会在下面展示它是如何工作的。

In the last checkout I cannot switch from 4.1 to 4.1.1, probably because the HEAD is already at the commit ...

或多或少,是的。更准确地说 "switching" 从 4.1 到 4.1.1 根本没有切换任何东西,因为 4.1 和 4.1.1 是同一个提交。 Git走捷径,什么都不写,因为什么都不用写。嗯,就是除了:

is there someway to force the "HEAD detached at N" without like checking out the master branch in this case and then checking out the tag.

git status 报告的 "detached at / from" 是基于 HEAD reflog 中留下的面包屑痕迹。当你 运行 git checkout <em>X</em> 一些 X 和 Git 更新 HEAD,Git 首先将 HEAD 当前 值保存到 HEAD 的 reflog 中,连同一条注释,比如这个:

8858448bb4 HEAD@{0}: checkout: moving from pu to master

(pu 是 Git 存储库中 Git 本身的 "proposed update" 或 "pickup" 分支,所以上面的条目是我的结果做 git checkout pu,它从 origin/pu 创建了 pu 并赋予它值 8265814db9543fbaf50c4db8133671ce64dc1ae4,然后是 git checkout master。从 master 到新创建的 [=19] 的运动=]制作了HEAD@{1},评论为checkout: moving from master to pu。)

HEAD 分离时,git status 所做的是通过 HEAD 的 reflog 来找到根目录,以尝试找到您在获取之前明确签出的分支或标记无论你现在做什么承诺。如果您现在所在的分离式 HEAD 提交与该分支或标记名称的值相匹配,则您在 Y 分离,其中 <em>Y</em> 来自评论。如果你现在的 detached-HEAD 提交 <em> 不 </em> 匹配(或者可能不是 <code>@{0}),git status 报告 从<em>Y</em> 而不是 在 <em>Y</em>.

分离

因此,如果您可以更新 reflog,则可以 git status 报告新内容。显而易见的方法是 git update-ref,但我试过了。这是发生了什么。首先我们设置情况:

$ git checkout v2.18.0
[snip]
HEAD is now at 53f9a3e157 Git 2.18
$ git tag haha
$ git checkout haha
HEAD is now at 53f9a3e157 Git 2.18
$ git reflog | head -1
53f9a3e157 HEAD@{0}: checkout: moving from master to v2.18.0

当然还有 git status 报告 "detached at v2.18.0"。所以:

$ git update-ref -m "moving from v2.18.0 to haha" HEAD HEAD
$ git reflog | head -1
53f9a3e157 HEAD@{0}: checkout: moving from master to v2.18.0

唉,git update-ref走了捷径,懒得更新reflog了。 (也许 git checkout haha did 调用了 reflog 更新代码,但是 that 走了捷径。)所以,是时候作弊了——注意我并不是在建议任何人实际这样做!—通过知道 HEAD reflog 更新只是向 .git/logs/HEAD:

添加一行
$ ed .git/logs/HEAD 
16108
$t$
$s/from master to v2.18.0/from v2.18.0 to haha/ 
w
16281
q
$ git reflog | head -2
53f9a3e157 HEAD@{0}: checkout: moving from v2.18.0 to haha
53f9a3e157 HEAD@{1}: checkout: moving from master to v2.18.0
$ git status
HEAD detached at haha
nothing to commit, working tree clean

$t$ 命令重复了最后一行;然后 $s/from master to v2.18.0/from v2.18.0 to haha/ 用新评论替换了评论。所以现在 git status 报告我们想要报告的内容。

很明显 git update-ref 使更新短路的错误。它也可能是一个重要或有用的优化,但如果是这样,应该有一些标志来启用优化或强制更新,基于哪个默认值被认为更重要。除了整个 git status 依赖于 reflog 之外,这个错误是无关紧要的。