我怎么会遇到分离的HEAD问题?

14

我从master分支检出了一个commit/branch,然后切换回master分支并写了一些内容。之后,我进行了提交,但结果是分离头状态。为什么?

以下是我的操作步骤:

  1. 创建一个新项目并创建git仓库。
  2. git add
  3. git commit
  4. 输入一些文字
  5. git commit
  6. 切换到先前的提交版本
  7. 切换回来

    step7

  8. 输入一些文字

  9. 尝试进行提交;提示出现了分离头。

    step9

IntelliJ IDEA控制台显示:

17:08:58.143: cd C:\Users\jiahao\IdeaProjects\testtt\src
17:08:58.143: git init
Initialized empty Git repository in C:/Users/jiahao/IdeaProjects/testtt/src/.git/
17:09:16.331: cd C:\Users\jiahao\IdeaProjects\testtt\src
17:09:16.331: git -c core.quotepath=false add --ignore-errors -- C.java
17:09:24.407: cd C:\Users\jiahao\IdeaProjects\testtt\src
17:09:24.407: git -c core.quotepath=false commit --only -F C:\Users\jiahao\AppData\Local\Temp\git-commit-msg-0.txt -- C.java
[master (root-commit) 22d1c79] first commit
 1 file changed, 6 insertions(+)
 create mode 100644 C.java

17:09:38.060: cd C:\Users\jiahao\IdeaProjects\testtt\src
17:09:38.060: git -c core.quotepath=false commit --only -F C:\Users\jiahao\AppData\Local\Temp\git-commit-msg-0.txt -- C.java
[master 69084f3] second commit
 1 file changed, 1 insertion(+)

17:09:44.136: cd C:\Users\jiahao\IdeaProjects\testtt\src
17:09:44.136: git -c core.quotepath=false checkout 22d1c7919eab50925411d9bbb8a9ad1575608c27
Note: checking out '22d1c7919eab50925411d9bbb8a9ad1575608c27'.
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 22d1c79... first commit
17:09:46.576: cd C:\Users\jiahao\IdeaProjects\testtt\src
17:09:46.576: git -c core.quotepath=false checkout 69084f344b79a48da92855d3fb633a28a672a302
Previous HEAD position was 22d1c79... first commit
HEAD is now at 69084f3... second commit
17:18:26.999: cd C:\Users\jiahao\IdeaProjects\testtt\src
17:18:26.999: git -c core.quotepath=false commit --only -F         C:\Users\jiahao\AppData\Local\Temp\git-commit-msg-0.txt -- C.java
[detached HEAD 783fbf2] third commit
1 file changed, 1 insertion(+)

7
我怀疑你不仅仅是回到了主分支。如果你能提供一个完整的示例(包括从 git init 开始的所有步骤),以便复现这个问题,那将非常有帮助。 - Jon Skeet
1
不,那不是一个确切的步骤集 - "checkout back"不能告诉我们你具体做了什么。最好从命令行执行,以使其比从IDE更清晰明了。 - Jon Skeet
1
同时在命令行中显示 git status 的结果。 - Jon Skeet
你能给我们列出与 git reflog 相关的行吗? - xeor
当我使用命令行尝试重现问题时,却失败了,因为它可以正常工作!所以我认为可能是 IntelliJ IDEA 的 BUG。稍后我会在 IntelliJ IDEA 中向您展示 reflog。谢谢。 - guo
显示剩余3条评论
3个回答

28

问题和解决方案

仔细检查 IntelliJ-IDEA 日志,可以发现问题的本质。在创建了您的前两个提交之后,您处于以下状态:

enter image description here

不知何故,你检出了第一个提交,这使你进入分离 HEAD 状态:

enter image description here

然后,类似地,您检出了第二个提交(恰好是您的 master 分支的末尾)。这仍将你置于分离 HEAD 状态:

enter image description here


您写道:

我从 master 检出了一个提交/分支 [...]

请注意。检出恰好是分支末端的提交与检出该分支不是等价的操作!


请注意,HEAD 现在直接指向一个提交,而不是一个分支。这就是“分离 HEAD”的定义。HEAD 指向与 master 相同的提交并未改变您处于分离 HEAD 的事实。


一些 IDE 可能不会清楚地指示您实际上处于分离 HEAD 状态。 长期以来,即使对于git log --decorate也没有明显显示您的HEAD指向master,还是直接指向master的末端。


然后你进行了第三个提交,该操作如预期所示,仍将您留在分离 HEAD 状态;您的 master 分支仍然指向第二个提交。

enter image description here

要退出分离 HEAD 状态,您需要重新将 HEAD 附加到一个分支(在本例中为 master)。如何操作取决于您想要做什么。以下是假定您可以访问 Git CLI 的情况:

  • 如果您想放弃第三个提交,只需运行:

    git checkout master
    

    否则您将最终回到这种情况:

    输入图像描述

  • 如果您想保留第三个提交并使 master 指向它,请运行

  • git branch -f master HEAD
    

    在此输入图像描述

    然后

     git checkout master
    

    输入图像描述

分手提示

在集成开发环境(IDE)中学习Git是一种灾难性的做法。 我建议您首先在命令行中建立起对Git的理解,然后再开始在GUI中使用Git,如果这样做可以提高您的工作效率。


2
小心。检出恰好是分支末端的提交并不等同于检出该分支!这真正让我这个60岁的脑袋清醒了一下!虽然我还在学习,但我必须说,我发现Intellij UI对我有所帮助,因为我至少已经开始使用Git了,在尝试通过CLI进行几次后。作为一个独立开发者,总是被复杂性和最小奖励所困扰。 - Geoff Kendall

3

在使用IntelliJ 2020.2开发Java Spring项目的过程中,我意外地遇到了“detached-HEAD”状态。这是我恢复正常状态的方法。

在Git工具窗口[Alt+9]中,分支“Log: origin/master”有3个标签: 黄色=HEAD、绿色=master、紫色=origin/master: label colors in git tool window

'HEAD'和'origin/master'应用于最新的提交 enter image description here 'master'应用于早期的提交 enter image description here.

要退出detached-head并将其重置为期望的状态“HEAD & master & origin/master都应用于分支的最新提交”,右键单击“master”节点“Remote”列表(位于历史记录左侧)下的选项,并选择“Checkout” enter image description here

这样就回到了分支的最新提交的常规状态 enter image description here


2

如果需要恢复一个脱离HEAD的分支,你可以:

git checkout master

这并不能修复当前分支。 - user1034912

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接