且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

检出Git标签导致“分离的HEAD状态”

更新时间:2023-01-17 18:36:48

好的,先说几句话略显简单。



git 中,标签(像许多其他事情)就是所谓的树林。这是指项目历史上的一个方面。树可以是标签,提交,日期说明符,序号说明符或许多其他的东西。



现在一个分支就像一个标签,但是可以移动。当你在一个分支上做一个提交时,分支被移动到你所做的新的提交,表明它是当前的位置。



您的 HEAD 是指向被认为是当前的分支的指针。通常当您克隆资源库时, HEAD 将指向 master ,而这又指向一个提交。然后,当您执行 git checkout experiment 之类的操作时,您将 HEAD 切换到实验分支,可能指向不同的提交。



现在解释。



当您执行 git checkout v2.0 ,您正在切换到分支未指向的提交。 HEAD 现在是分离的,而不是指向一个分支。如果您决定立即进行提交(可能),则没有分支指针来更新以跟踪此提交。切换回另一个提交将使您失去您所做的新提交。这就是信息告诉你的。



通常,您可以做的是说 git checkout -b v2.0-fixes v2.0 。这将在树状 v2.0 (这种情况下的标签)指向的提交中创建一个新的分支指针,然后将您的 HEAD 指出。现在,如果您提交,可以跟踪它们(使用 v2.0-fixes 分支),您可以像通常一样工作。没有什么错与你所做的,特别是如果你只想看看 v2.0 代码。但是,如果您想要进行任何您想跟踪的更改,则需要一个分支。



您应该花一些时间了解git的所有DAG模型。令人惊讶的是,所有命令都很清楚。


I'm developing a deployment script for my git project and I just started using tags. I've added a new tag called v2.0:

git tag -a v2.0 -m "Launching version 2.0"

And I've pushed this tag to the remote repository

git push --tags

When I try to execute the deployment script and check out the v2.0 tag I get this message:

You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at

Is that normal? The repository is in limbo because if I do:

git branch

I get this output:

* (no branch)
  master

Sorry if this is obvious but I couldn't figure it out.

Okay, first a few terms slightly oversimplified.

In git, a tag (like many other things) is what's called a treeish. It's a way of referring to a point in in the history of the project. Treeishes can be a tag, a commit, a date specifier, an ordinal specifier or many other things.

Now a branch is just like a tag but is movable. When you are "on" a branch and make a commit, the branch is moved to the new commit you made indicating it's current position.

Your HEAD is pointer to a branch which is considered "current". Usually when you clone a repository, HEAD will point to master which in turn will point to a commit. When you then do something like git checkout experimental, you switch the HEAD to point to the experimental branch which might point to a different commit.

Now the explanation.

When you do a git checkout v2.0, you are switching to a commit that is not pointed to by a branch. The HEAD is now "detached" and not pointing to a branch. If you decide to make a commit now (as you may), there's no branch pointer to update to track this commit. Switching back to another commit will make you lose this new commit you've made. That's what the message is telling you.

Usually, what you can do is to say git checkout -b v2.0-fixes v2.0. This will create a new branch pointer at the commit pointed to by the treeish v2.0 (a tag in this case) and then shift your HEAD to point to that. Now, if you make commits, it will be possible to track them (using the v2.0-fixes branch) and you can work like you usually would. There's nothing "wrong" with what you've done especially if you just want to take a look at the v2.0 code. If however, you want to make any alterations there which you want to track, you'll need a branch.

You should spend some time understanding the whole DAG model of git. It's surprisingly simple and makes all the commands quite clear.