26 题: 如何将分离的HEAD与master / origin协调?

在...创建的问题 Mon, May 29, 2017 12:00 AM

我是Git分支复杂的新手。我总是在一个分支上工作并提交更改,然后定期推送到我的远程源。

最近某个地方,我重置了一些文件以使它们脱离提交暂存,后来又做了一个rebase -i来摆脱最近几次本地提交。现在我处于一种我不太了解的状态。

在我的工作区域,git log显示了我所期待的 - 我在正确的火车上,我不想要的提交,以及那些新的等等。

但是我只是推送到远程存储库,而且有什么不同 - 我在rebase中杀死的一些提交被推送,而本地提交的新提交不在那里。

我认为“master /origin”与HEAD分离,但我并不是100%清楚这意味着什么,如何使用命令行工具将其可视化,以及如何解决它。

    
1427
  1. 你是否在rebase之前推送了提交?
    2011-04-24 18:02:49Z
  2. @ manojlds:不确定你的意思。我在推销前推了一段时间,但不是在此之前。
    2011-04-24 18:18:48Z
  3. 就像之前推送你在rebase -i中删除的提交一样。从你的回答中我认为不是。
    2011-04-24 18:22:59Z
  4. @ manojlds:正确。我只杀了比最近的推送更近的提交。 (虽然正如我所提到的,我已经推了,因为我觉得一切都还可以)
    2011-04-24 18:23:44Z
  5. 你能解释一下你在I did a reset of some files to get them out of commit staging中做了什么吗?抱歉问题:)
    2011-04-24 18:31:58Z
  6. 醇>
    26答案                              26 跨度>                         

    首先,让我们澄清一下 HEAD是什么 以及分离时的含义。

    HEAD是当前签出提交的符号名称。当HEAD没有分离时(“正常” 1 情况:你有一个分支检出),HEAD实际指向分支的“ref”,分支指向提交。因此HEAD“附着”到分支。进行新提交时,HEAD指向的分支将更新为指向新提交。 HEAD会自动跟随,因为它只指向分支。

    •  git symbolic-ref HEAD收益refs/heads/master
      名为“master”的分支已签出。
    •  git rev-parse refs/heads/master产量17a02998078923f2d62811326d130de991d1a95a
      该提交是主分支的当前提示或“头”。
    •  git rev-parse HEAD也收益17a02998078923f2d62811326d130de991d1a95a
      这就是“象征性的参考”意味着什么。它通过其他参考指向一个对象 (符号引用最初是作为符号链接实现的,但后来更改为具有额外解释的普通文件,以便它们可以在没有符号链接的平台上使用。)

    我们有HEADrefs/heads/master17a02998078923f2d62811326d130de991d1a95a

    当分离HEAD时,它直接指向提交 - 而不是通过分支间接指向一个提交。您可以将分离的HEAD视为未命名的分支。

    •  git symbolic-ref HEADfatal: ref HEAD is not a symbolic ref失败
    •  git rev-parse HEAD收益17a02998078923f2d62811326d130de991d1a95a
      由于它不是符号引用,它必须直接指向提交本身。

    我们有HEAD17a02998078923f2d62811326d130de991d1a95a

    使用分离的HEAD要记住的重要一点是,如果它指向的提交是未引用的(没有其他引用可以到达它),那么当你签出其他提交时它将变成“悬空”。最终,这些悬空提交将通过垃圾收集过程进行修剪(默认情况下,它们会被保存至少2周,并且可以通过HEAD的reflog引用来保持更长时间。)

    1 使用独立的HEAD完成“正常”工作是完全正常的,你只需要跟踪你正在做的事情,以避免不得不从reflog中删除历史记录。


    交互式rebase的中间步骤是使用分离的HEAD完成的(部分是为了避免污染活动分支的reflog)。如果完成完整的rebase操作,它将使用rebase操作的累积结果更新原始分支,并将HEAD重新附加到原始分支。我的猜测是你从未完全完成变基过程;这将为您留下一个分离的HEAD,指向最近由rebase操作处理的提交。

    要从您的情况中恢复,您应该创建一个分支,指向分离的HEAD当前指向的提交:

     
    git branch temp
    git checkout temp
    

    (这两个命令可以缩写为git checkout -b temp

    这会将你的HEAD重新连接到新的temp分支。

    接下来,您应该将当前提交(及其历史记录)与您希望工作的正常分支进行比较:

     
    git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
    git diff master temp
    git diff origin/master temp
    

    (您可能希望尝试使用日志选项:添加-p,不要使用--pretty=…查看整个日志消息等。)

    如果您的新temp分支看起来不错,您可能需要更新(例如)master以指向它:

     
    git branch -f master temp
    git checkout master
    

    (这两个命令可以缩写为git checkout -B master temp

    然后您可以删除临时分支:

     
    git branch -d temp
    

    最后,您可能希望推送重新建立的历史记录:

     
    git push origin master
    

    您可能需要在此命令的末尾添加--force以推送远程分支无法“快速转发”到新提交(即您删除,或重写一些现有提交,或以其他方式重写一些历史)。

    如果您正在进行rebase操作,您应该清理它。您可以通过查找目录.git/rebase-merge/来检查是否正在使用rebase。您可以通过删除该目录来手动清理正在进行的rebase(例如,如果您不再记住活动rebase操作的目的和上下文)。通常你会使用git rebase --abort,但这会做一些你可能想要避免的额外重置(它将HEAD移回原始分支并将其重置回原始提交,这将撤消我们上面所做的一些工作)。

        
    2367
    2019-01-15 18:16:21Z
    1. 有趣的是man git-symbolic-ref:“过去,.git/HEAD是指向refs/heads/master的符号链接。当我们想切换到另一个分支时,我们做了ln -sf refs/heads/newbranch .git/HEAD,当我们想要的时候为了找出我们所在的分支,我们做了readlink .git/HEAD.但是符号链接不是完全可移植的,所以现在它们已被弃用,默认情况下使用符号引用(如上所述)。“
      2013-08-02 02:43:56Z
    2. 这个答案是帮助我在意外地执行git重置后让我的原点/主人与我的本地同步的最后一步--hard< sha>在Eclipse中。第一步是做一个git reflog并恢复本地提交(参见 stackoverflow.com/questions/5473/undoing-a-git-reset-hard-head1 )。谢谢。
      2013-11-27 15:02:12Z
    3. 我同意@AntonioSesto:对于大多数项目(甚至是相当大的项目),你不需要令人难以置信的复杂性,即Git。我的大脑反对努力克服过于明显过度设计的事情。我不需要它,我也不需要它。
      2015-09-17 11:24:52Z
    4. 这是一个很好的答案,但我认为不需要临时分支(虽然我通常使用自己的一个)。 git branch -f master HEAD && git checkout master就足够了 - 假设你的目标是保持目前的头脑,但将其指定为master。其他目标也有意义,并要求其他食谱。
      2015-11-06 10:28:43Z
    5. Lol在关于长度的评论中。而我们其他人只是扫描直到我们到达“从你的情况中恢复[...]”这一行,并从那里开始 - 同时做一个心理记录还有一个有用的,很好解释的背景故事,我们可以在下雨天阅读。 选项阅读更多内容并不会对您造成伤害,但确实会让其他人受益。
      2016-03-10 22:53:13Z
    6. 醇>

    这样做:

     
    git checkout master
    

    或者,如果您要保留更改,请执行以下操作:

     
    git checkout -b temp
    git checkout -B master temp
    
        
    586
    2017-01-25 00:12:44Z
    1. 谢谢你的简洁。不是每个人都有时间参加“首先,让我们澄清一下HEAD是什么......”回答。
      2016-02-28 12:58:51Z
    2. 这是一个危险的回应。到达这个答案的人有不同的状态,“只是做这个来解决它”回答不回答问题。这个很容易破坏工作。
      2016-03-10 18:51:22Z
    3. !“git checkout master”如果分离的头部不是master的一部分,将导致所有更改都丢失!!
      2016-03-28 20:53:50Z
    4. @ Blauhirn你可能已经签出了提交,而不是分支。分支仍指向相同的提交,但您处于不同的“模式”。
      2016-06-13 01:12:42Z
    5. git reset应该带有警告“如果你不知道你在做什么,就停止它”。从一小时的恐怖思想中恢复过来,我已经失去了上周的工作。谢谢!
      2016-06-13 01:26:19Z
    6. 醇>

    我遇到了这个问题,当我读到最高投票答案时:

      

    HEAD是当前签出提交的符号名称。

    我想:啊哈!如果HEAD是当前结账提交的符号名称,我可以通过将其与master进行重新调整来将其与master进行协调:  
    git rebase HEAD master
    

    此命令:

    1. 退房master
    2. HEAD的父提交标识回HEADmaster分开的点
    3. master之上播放这些提交
    4. 醇>

      最终结果是HEAD但不是master的所有提交也都在master中。 master仍然签出。


      关于遥控器:

        

      我在rebase中杀死的一些提交被推了出来,并且在本地提交的新提交不在那里。

      无法再使用您的本地历史记录快速转发远程历史记录。您需要强制推送(git push -f)来覆盖远程历史记录。如果您有任何合作者,通常可以与他们进行协调,这样每个人都在同一页面上。

      master推送到远程origin后,您的远程跟踪分支origin/master将更新为指向与master相同的提交。

          
    117
    2017-09-27 21:38:34Z
    1. git:“首先,倒带头重播你的工作......快速转发大师到HEAD。”我:“太好了!”
      2015-09-10 22:37:47Z
    2. 非常酷!!!!
      2019-03-27 00:29:41Z
    3. 醇>

    在这里查看分离头的基本解释:

    http://git-scm.com/docs/git-checkout

    visu的命令行把它弄清楚:

     
    git branch
    

     
    git branch -a
    

    您将获得如下输出:

     
    * (no branch)
    master
    branch1
    

    * (no branch)显示你处于分离状态。

    你可以通过做git checkout somecommit等来达到这个状态,它会警告你:

      

    你处于'超级HEAD'状态。您   可以环顾四周,做实验   改变并提交它们,你可以   放弃你在此提交的任何提交   国家不影响任何分支机构   通过再次结账。

         

    如果要创建新分支   保留您创建的提交,您可以这样做   所以(现在或以后)使用-b和   再次结帐命令。例如:

         

    git checkout -b new_branch_name

    现在,让他们成为主人:

    执行git reflog甚至只需git log并记下您的提交。现在git checkout mastergit merge提交。

     
    git merge HEAD@{1}
    

    编辑:

    要添加,请使用git rebase -i不仅可以删除/删除不需要的提交,还可以编辑它们。只需在提交列表中提及“编辑”,您就可以修改您的提交,然后发出git rebase --continue继续。这样可以确保你永远不会进入一个独立的HEAD。

        
    80
    2011-04-24 18:52:42Z
    1. 感谢此处的细节和重要信息指示。似乎没有必要进行显式合并,但这可以看到我将回到的一些概念。感谢。
      2011-04-24 21:42:41Z
    2. “@ {1}”做什么?
      2015-05-01 16:11:27Z
    3. 醇>

    将您的分离提交添加到自己的分支

    只需运行git checkout -b mynewbranch

    然后运行git log,你会在这个新分支上看到提交现在是HEAD

        
    30
    2013-05-20 02:44:42Z
    1. 如果我这样做,mynewbranch会附加到任何东西吗?
      2015-10-05 15:00:19Z
    2. 是的,它附加到分离的头部所附着的位置,这正是我想要的。谢谢!
      2015-10-06 11:01:59Z
    3. 醇>

    如果您只有主分支并希望回到“开发”或功能只是这样做:

     
    git checkout origin/develop
    

    注意:退房 origin /develop

    您处于分离的HEAD 状态。你可以环顾四周,做实验 更改并提交它们,您可以放弃您在此中提交的任何提交 通过执行另一次结账而不影响任何分支的状态...

    然后

     
    git checkout -b develop
    

    它有效:)

        
    21
    2016-05-12 08:19:55Z
    1. 对我有用的不是'git checkout origin /develop'而是'git checkout develop'。使用'origin /develop'总是没有变化,因此留在“HEAD脱离原点/开发”。跳过'origin'部分修复了所有内容。
      2014-04-23 18:58:19Z
    2. 醇>

    如果您想推送当前已分离的HEAD(请先检查git log),请尝试:

     
    git push origin HEAD:master
    

    将分离的HEAD发送到原始分支。如果您的推送被拒绝,请先尝试git pull origin master从原点获取更改。如果你不关心来自原点的变化而被拒绝,因为你做了一些有意的变更并且你想要替换ori与您当前分离的分支的杜松子酒/主人 - 然后您可以强制它(-f)。如果您失去了对先前提交的访问权限,您可以随时运行git reflog以查看所有分支的历史记录。


    要在保持更改的同时返回主分支,请尝试以下命令:

     
    git rebase HEAD master
    git checkout master
    

    请参阅: Git:“目前不在任何分支上。”是否有一种简单的方法可以在保留更改的同时返回分支机构?

        
    16
    2017-05-23 10:31:37Z
    1. 这确实将分离的提交发送给origin /master。要将头部连接到本地分支,请执行以下操作: stackoverflow.com/a/17667057/776345
      2016-07-13 07:21:00Z
    2. 当我这样做时,我得到了这个存储库是为Git LFS配置的,但在你的路径上找不到'git-lfs'。如果您不再希望使用Git LFS,请删除.git /hooks /post-checkout删除此挂钩。
      2018-03-12 18:07:50Z
    3. 醇>

    我今天遇到了这个问题,我很确定通过这样做解决了这个问题:

     
    git branch temp
    git checkout master
    git merge temp
    

    当我弄清楚如何做到这一点时,我在我的工作电脑上,现在我在个人电脑上遇到了同样的问题。因此,我必须等到周一,当我回到工作计算机上,看看我是怎么做的。

        
    10
    2018-08-20 15:24:44Z
    1. 第二个git命令似乎错了..
      2015-03-06 13:20:27Z
    2. @ StarShine Kenorb修复了它。现在它将分离的提交保存到新的分支,temp,切换到master,并将temp合并到master。
      2016-01-15 10:42:21Z
    3. 我不知道为什么ppl正在贬低这个,它修复了我的问题统计数据,但你可能想要包含delete temp branch命令。
      2016-03-23 04:58:09Z
    4. 醇>

    以下对我有用(仅使用分支主控):

     
    git push origin HEAD:master
    git checkout master        
    git pull
    

    第一个将分离的HEAD推送到远程原点。

    第二个移动到分支主人。

    第三个恢复附加到分支主人的HEAD。

    如果推送被拒绝,第一个命令可能会出现问题。但这不再是分离头的问题,而是关于分离的HEAD不知道某些远程变化的事实。

        
    9
    2018-01-07 12:31:49Z
    1. 没有用,我得到了:这个存储库是为Git LFS配置的,但在你的路径上找不到'git-lfs'。如果您不再希望使用Git LFS,请删除.git /hooks /pre-push以删除此挂钩。你目前不在分公司。请指定要合并的分支。
      2018-03-12 16:59:59Z
    2. 醇>

    如果你完全确定HEAD是好状态:

     
    git branch -f master HEAD
    git checkout master
    

    你可能无法推动原点,因为你的主人已经偏离了原点。如果您确定没有其他人使用回购,您可以强行推送:

     
    git push -f
    

    如果您在其他人没有使用的功能分支上,则最有用。

        
    8
    2016-03-15 11:01:13Z
    1. 正确的答案就在那里
      2016-12-13 06:28:00Z
    2. 醇>

    你所要做的就是'git checkout [branch-name]',其中[branch-name]是你进入一个独立头状态的原始分支的名称。 (与asdfasdf分离)将消失。

    例如,在分支'dev'中,您检查提交asdfasd14314 - >

     
    'git checkout asdfasd14314'
    

    你现在处于一个独立的头状态

    'git branch'将列出类似 - >

    的内容  
    * (detached from asdfasdf)
      dev
      prod
      stage
    

    但是要离开分离的头状态并回到dev - >

     
    'git checkout dev'
    

    然后'git branch'将列出 - >

     
    * dev
      prod
      stage
    

    但当然,如果你不打算保持对分离头部状态的任何改变,但我发现自己做了很多事情并不打算做任何修改而只是看看之前的提交

        
    6
    2014-10-17 19:49:18Z

    正如克里斯指出的那样,我有以下情况

    git symbolic-ref HEADfatal: ref HEAD is not a symbolic ref

    失败

    然而,git rev-parse refs/heads/master指向了我可以恢复的良好提交(在我的情况下,最后一次提交,你可以通过使用git show [SHA]看到提交

    之后我做了很多混乱的事情,但似乎修复的只是,

    git symbolic-ref HEAD refs/heads/master

    头部重新连接!

        
    6
    2017-10-11 10:16:48Z
    1. 谢谢!我的头已经超然了。我可以把它赶上主人,但他们恰好指向同一个提交,而不是指向指向提交的主人。好的小费= D
      2018-03-22 19:51:42Z
    2. 醇>
    而不是做git checkout origin/master

    只做git checkout master

    然后git branch将确认您的分支。

        
    4
    2016-08-05 14:08:07Z

    今天我遇到了这个问题,我更新了一个子模块,但没有在任何分支上。我已经承诺了,所以藏匿,结账,捣乱都行不通。我结束了挑选超然的头部的承诺。所以我提交后立即(当推送失败时),我做了:

     
    git checkout master
    git cherry-pick 99fe23ab
    

    我的想法是:我在一个超然的头上,但我想成为主人。假设我的分离状态与master没什么不同,如果我可以将我的提交应用到master,我会被设置。这正是樱桃选择的目的。

        
    4
    2018-04-11 05:58:54Z

    我在搜索You are in 'detached HEAD' state.

    时发现了这个问题

    在分析了我到达这里所做的事情之后,与我过去所做的相比,我发现我犯了一个错误。

    我的正常流程是:

     
    git checkout master
    git fetch
    git checkout my-cool-branch
    git pull
    

    这次我做了:

     
    git checkout master
    git fetch
    git checkout origin/my-cool-branch
    # You are in 'detached HEAD' state.
    

    问题在于我不小心做了:

     
    git checkout origin/my-cool-branch
    

    而不是:

     
    git checkout my-cool-branch
    

    修复(在我的情况下)只是运行上面的命令,然后继续流程:

     
    git checkout my-cool-branch
    git pull
    
        
    4
    2018-11-30 19:52:19Z

    如果你在主人之上做了一些提交并且只想在那里“向后合并”master(即你想要master指向HEAD),那么单行将是:

     
    git checkout -B master HEAD
    
    1. 这会创建一个名为master的新分支,即使它已经存在(这就像移动master,这就是我们想要的)。
    2. 新创建的分支设置为指向HEAD,这就是您所在的位置。
    3. 新分支已签出,因此您之后将使用master.
    4. 醇>

      我发现这在子存储库的情况下特别有用,它也恰好经常处于分离状态。

          
    3
    2017-04-07 14:14:03Z

    我遇到了同样的问题,我已经通过以下步骤解决了这个问题。

    如果您需要保留更改

    1. 首先,你需要运行git checkout master命令让你回到主人 分支。
    2. 如果您需要保留更改,请运行git checkout -b changes和  git checkout -B master changes
    3. 醇>

      如果您不需要更改

      1. 从分支运行git clean -df中删除所有未跟踪的文件。

      2. 然后,您需要清除存储库中的所有未分级更改。为此,您必须运行git checkout --

      3. 最后,您必须使用git checkout master命令将分支放回主分支。

    3
    2017-12-27 11:53:34Z

    对我而言,它就像再次删除本地分支一样简单,因为我没有任何我想推送的本地提交:

    所以我做了:

     
    git branch -d branchname
    

    然后再次检查分支:

     
    git checkout branchname
    
        
    3
    2018-08-20 15:25:24Z

    当我个人发现自己处于这样的情况时,我发现我在master时没有做出一些更改(即HEADmaster正上方分离,而且之间没有任何提交)存储可能会有所帮助:

     
    git stash # HEAD has same content as master, but we are still not in master
    git checkout master  # switch to master, okay because no changes and master
    git stash apply  # apply changes we had between HEAD and master in the first place
    
        
    1
    2017-10-11 21:03:12Z

    简单来说,分离的HEAD状态意味着您没有签出任何分支的HEAD(或提示)

    了解示例

    大多数情况下的分支是多个提交的序列,如:

    提交1: 主 - > branch_HEAD(123be6a76168aca712aea16076e971c23835f8ca)

    提交2: 主 - > 123be6a76168aca712aea16076e971c23835f8ca - > branch_HEAD(100644a76168aca712aea16076e971c23835f8ca)

    正如您在提交序列的情况下所看到的,您的分支指向您的最新提交。因此,在这种情况下,如果你签出提交 123be6a76168aca712aea16076e971c23835f8ca 那么你将处于分离头状态,因为你的分支的HEAD指向 100644a76168aca712aea16076e971c23835f8ca 并且从技术上讲,你在HEAD检查了否科。因此,您处于分离的HEAD状态。

    理论解释

    在此博客中它显然是在陈述 Git存储库是一个提交树,每个提交指向其祖先,每个提交指针都会更新,这些指向每个分支的指针都存储在.git /refs子目录中。标签存储在.git /refs /tags中,分支存储在.git /refs /heads中。如果您查看任何文件,您会发现每个标记对应一个文件,具有40个字符的提交哈希值,如上所述@Chris Johnsen和@Yaroslav Nikitenko,您可以查看这些引用。

        
    1
    2018-08-20 15:28:12Z

    我陷入了一个非常愚蠢的状态,我怀疑其他人会发现这个有用......但是以防万一

     
    git ls-remote origin
    0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b        HEAD
    6f96ad0f97ee832ee16007d865aac9af847c1ef6        refs/heads/HEAD
    0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b        refs/heads/master
    

    我最终用

    修复了  
    git push origin :HEAD
    
        
    0
    2013-10-18 03:14:19Z

    这完全适合我:

    1。 git stash保存您的本地修改

    如果您想放弃更改,请访问git clean -df
    git checkout -- .
    git clean删除所有未跟踪的文件(警告:虽然它不会删除.gitignore中直接提到的忽略文件,但它可能会删除驻留在文件夹中的忽略文件),git checkout会清除所有未分级的更改。

    2。 git checkout master切换到主分支(假设你要使用master)
    3. git pull从主分支拉取最后一次提交
    4. git status为了检查一切看起来很棒

     
    On branch master
    Your branch is up-to-date with 'origin/master'.
    
        
    0
    2017-08-24 07:25:34Z

    在我的情况下,我运行了git status,我看到我的工作目录中有一些未跟踪的文件。

    为了使rebase工作,我只需要清理它们(因为我不需要它们)。

        
    0
    2018-08-20 15:25:47Z

    如果您在Eclipse中使用 EGit : 假设您的主人是您的主要发展分支

    • 将您更改为分支,通常是新分支
    • 然后从遥控器拉
    • 然后右键单击项目节点,选择团队,然后选择显示历史记录
    • 然后右键单击主人,选择结帐
    • 如果Eclipse告诉你,有两个主人,一个本地一个遥控器,选择遥控器

    在此之后你应该能够重新连接到原始主人。

        
    0
    2018-08-20 18:57:39Z

    我遇到了同样的问题。我把我的变化藏起来了  git stash和硬重置本地分支到先前的提交(我认为它导致了)然后做了一个git pull,我现在没有得到分离。别忘了git stash apply再次进行更改。

        
    - 1
    2018-11-05 14:42:34Z
     
    git checkout checksum  # You could use this to peek previous checkpoints
    git status # You will see HEAD detached at checksum
    git checkout master # This moves HEAD to master branch
    
        
    - 2
    2018-08-20 15:26:36Z
来源放置 这里