为什么我的Git回购进入了分离的HEAD状态?


386

今天我结了一个头,这是与以下描述相同的问题:git push表示所有内容都是最新的,即使我进行了本地更改

据我所知,我没有做任何异常的事情,只是从本地仓库中提交和推送。

那我怎么最终得到一个detached HEAD


18
签出远程分支似乎是意外执行此操作的最常用方法;另一种常见的方式是结帐branch-name@{n},即的第n个位置branch-name。但是无论如何,在某个时候一定有一个git checkout <rev>。如果这没有敲响,那可能是您做了Will所提到的-尝试这样做,git checkout <file>并偶然指定了一个修订版本。
卡斯卡贝尔

3
有关撤消HEAD分离状态的信息,请参见修复Git分离头?

重新部署期间遇到冲突时,我的回购以这种状态结束。幸运的是,吉特(Git)告诉我跑步时该怎么做git statusall conflicts fixed: run "git rebase --continue"
保罗

2
如果您不小心输入git checkout remotes/origin/my-branch而不是git checkout my-branch或,也会发生这种情况git checkout origin/my-branch
亚当·里布沙(AdamLibuša)

@adam Libusa,感谢它为我工作。git checkout remotes / origin / my-branch和git checkout my-branch有什么区别?是不一样的。但是你说的对我有用 出于好奇,我问。
karunakar bhogyari

Answers:


280

如果提交的签出不是您的分支之一的名称,则将获得一个分离的HEAD。代表分支尖端的SHA1仍然给出分离的HEAD。仅签出本地分支名称可以避免该模式。

请参见使用分离的HEAD提交

分离HEAD时,除了没有命名分支得到更新之外,提交工作与正常工作相同。(您可以将其视为匿名分支。)

替代文字

例如,如果您在未先跟踪的情况下签出“远程分支”,则可能会得到一个分离的HEAD。

参见git:切换分支而不拆卸头部


使用Git 2.23(2019年8月),您不再需要使用令人困惑的git checkout命令

git switch 也可以签出一个分支,并获得一个分离的HEAD,除了:

  • 它有一个明确的--detach选择

要在HEAD~3不创建新分支的情况下签出提交以进行临时检查或实验,请执行以下操作:

git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
  • 它不能错误地分离远程跟踪分支

看到:

C:\Users\vonc\arepo>git checkout origin/master
Note: switching to 'origin/master'.

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 switching back to a branch.

VS. 使用新git switch命令:

C:\Users\vonc\arepo>git switch origin/master
fatal: a branch is expected, got remote branch 'origin/master'

如果要创建一个跟踪远程分支的新本地分支:

git switch <branch> 

如果<branch>未找到,但确实在一个<remote>具有匹配名称的远程站点(称为)中存在跟踪分支,则将其视为等效于

git switch -c <branch> --track <remote>/<branch>

没有更多的错误!
不再有多余的超脱头!


12
进入独立头状态的另一种方法是,如果您处于交互式基础的中间,并且您要编辑其中一个提交。当Git将您置于要编辑的提交位置时,您将处于独立状态,直到完成变基。

在此直观指南中,有一个解释:git commit files creates a new commit containing the contents of the latest commit, plus a snapshot of files taken from the working directory. Additionally, files are copied to the stage.“将文件复制到舞台上”是什么意思?我以为文件已提交,这意味着阶段已清除?
最高

16
实际上,无论何时通过SHA1 检入任何提交,无论是否在分支的顶端,您都将获得一个分离的HEAD 。可以在不获取HEAD的情况下签出的唯一一种方法是分支名称。例如,即使mastered489上面的图中的上,git checkout ed489也会为您提供独立的HEAD,而git checkout master不会。
musiphil

8
"You can think of this as an anonymous branch":)我喜欢类比
Adrien Be


117

我刚才偶然复制了这个:

  1. 列出远程分支

    git branch -r
          origin/Feature/f1234
          origin/master
    
  2. 我想在本地结帐,所以我剪切了粘贴:

    git checkout origin/Feature/f1234
    
  3. 快点!分离的HEAD状态

    You are in 'detached HEAD' state. [...])
    

解决方案1:

origin/签出时不要包括在我的分支规范的前面:

git checkout Feature/f1234

解决方案2:

添加-b参数以从远程创建本地分支

git checkout -b origin/Feature/f1234 要么

git checkout -b Feature/f1234 它会自动回原点


14
这几乎是一个很好的答案,但是无法解释为什么您进入了独立的头脑状态。

5
我同意,但确实提供了我正在寻找的解决方案。谢谢!!
Kilmazing

我在另一个答案中看到git checkout -b Feature/f1234<=> git branch Feature/f1234git checkout Feature/f1234
Armfoot

1
默认情况下,它看起来是起源的,所以当您给出时origin/branchname,它会寻找 origin/origin/branchname第一个是您使用的远程名称-b,如果您不这样做,它将创建一个anonymous分离的分支。同样,要从其他远程签出,则必须提及-b参数,否则git无法知道是从新远程签入的方式,它将寻找origin/remote/branchname
garg10may

你是圣人!
哈维·林

12

尝试

git reflog 

这为您提供了过去如何移动HEAD和分支指针的历史记录。

例如:

88ea06b HEAD @ {0}:结帐:从开发迁移到远程/起源/ SomeNiceFeature e47bf80 HEAD @ {1}:拉起原点开发:快速前进

此列表的顶部是一个原因,一个人可能会遇到DETACHED HEAD状态……签出远程跟踪分支的原因。


7

如果您尝试撤消通过重新签出文件而没有完全正确使用语法所做的更改,则很容易发生这种情况。

您可以看一下的输出git log-您可以将自上次成功提交以来的日志尾部粘贴到此处,我们都可以看到您所做的事情。或者,您可以将其粘贴并#git在freenode IRC上很好地询问。


5

如果您有一个与分支相同的名称,则可能会发生这种情况。

示例:如果“ release / 0.1”是标签名称,则

git checkout release/0.1

在“ release / 0.1”处生成分离的HEAD。如果您希望release / 0.1是分支名称,那么您会感到困惑。


1
是。但是如何解决呢?您如何在分支机构结帐?
马丁

5

Detached HEAD 表示当前检出的不是本地分支。

导致Detached HEAD状态的某些情况:

  • 如果您签出远程分支,请说origin/master。这是一个只读分支。因此,从中创建提交origin/master时将是自由浮动的,即未连接到任何分支。

  • 如果签出特定标签或提交。从此处进行新的提交时,它将再次自由浮动,即未连接到任何分支。请注意,签出分支时,新提交始终总是自动放在提示处。

    当您想返回并签出特定的提交或标记以从那里开始工作时,可以创建一个源自该提交的新分支,并通过切换到该分支git checkout -b new_branch_name。这将阻止Detached HEAD状态,因为您现在已签出分支而不是提交。


3

一种简单的偶然方式是做git checkout head一个错字HEAD

尝试这个:

git init
touch Readme.md
git add Readme.md
git commit
git checkout head

这使

Note: checking out 'head'.

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 9354043... Readme

longair.net/blog/2012/05/07/the-most-conusing-git-terminology中也提到了(查找“ HEAD”和“ head””)
VonC

@VonC:感谢您的链接。我正在准备Git培训,我也想指出为什么有时会如此令人困惑。我已经有很多示例了(例如checkout -b看起来像一个结帐但实际上是分支),但是欢迎其他列表。
Thomas Weller

2

进入git分离头状态的另一种方法是尝试提交到远程分支。就像是:

git fetch
git checkout origin/foo
vi bar
git commit -a -m 'changed bar'

请注意,如果执行此操作,则进一步尝试检出origin / foo的操作将使您回到独立的状态!

解决方案是创建自己的本地foo分支,以跟踪origin / foo,然后选择推送。

这可能与您的原始问题无关,但是此页面在谷歌上搜索“ git detached head”的命中率很高,并且这种情况严重不足。


这种情况似乎就是上述Owen讨论的问题-剪切和粘贴“ origin / foo”使git认为它是“ origin / origin / foo”。
mvanle

1

当您签出提交git checkout <commit-hash>或远程分支时,HEAD将分离,并尝试在其上创建新的提交。

30天后,所有分支或标签均无法访问的提交将被垃圾收集并从存储库中删除。

解决此问题的另一种方法是为新创建的提交创建一个新分支,并对其进行检出。 git checkout -b <branch-name> <commit-hash>

本文说明了如何达到分离的HEAD状态。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.