How can I reconcile detached HEAD with master/origin?
我对Git的分支复杂性是个新手。我总是在一个分支上工作,提交更改,然后定期地推送到我的远程源站。
最近的某个地方,我对一些文件进行了重置,以使它们脱离提交阶段,然后执行了
在我的工作区域,
但我只是推到了远程存储库,有什么不同——我在REBASE中杀死的两个提交被推了,而在本地提交的新提交不在那里。
我认为"master/origin"与head是分离的,但我并不完全清楚这意味着什么,如何使用命令行工具可视化它,以及如何修复它。
首先,让我们澄清什么是头,当它被分离时它意味着什么。好的。
head是当前签出提交的符号名。当head未被分离时("normal"1情况:您签出了一个分支),head实际指向分支的"ref",分支指向commit。因此,头部"附着"在树枝上。当您进行新的提交时,head指向的分支将被更新为指向新的提交。头部自动跟随,因为它只是指向分支。好的。
git symbolic-ref HEAD 生成refs/heads/master 。名为"master"的分支已签出。git rev-parse refs/heads/master 产量17a02998078923f2d62811326d130de991d1a95a 。该提交是主分支的当前提示或"head"。git rev-parse HEAD 也产生17a02998078923f2d62811326d130de991d1a95a 。这就是所谓的"符号参考"。它通过其他引用指向一个对象。(符号引用最初是作为符号链接实现的,但后来改为带有额外解释的普通文件,以便可以在没有符号链接的平台上使用。)
我们有
分离head时,它直接指向commit,而不是通过分支间接指向commit。你可以把一个分开的脑袋想象成是在一个无名的树枝上。好的。
git symbolic-ref HEAD 与fatal: ref HEAD is not a symbolic ref 故障git rev-parse HEAD 生成17a02998078923f2d62811326d130de991d1a95a 。因为它不是一个符号引用,所以必须直接指向提交本身。
我们有
使用分离的头要记住的重要一点是,如果它指向的提交没有被引用(没有其他引用可以到达它),那么当您签出其他提交时,它将成为"悬空的"。最终,这些挂起的提交将通过垃圾收集过程进行修剪(默认情况下,这些提交将保留至少2周,并且可以通过head的reflog引用保留更长的时间)。好的。
一用一个独立的脑袋做"正常"的工作是非常好的,你只需要跟踪你正在做的事情就可以避免从反射波中捕捉掉的历史。好的。
交互钢筋的中间步骤是用一个分离的头完成的(部分是为了避免污染活动分支的回流)。如果您完成了完整的REBASE操作,它将使用REBASE操作的累积结果更新原始分支,并将头重新附加到原始分支。我的猜测是,您从未完全完成REBASE过程;这将使您有一个独立的头指向最近由REBASE操作处理的提交。好的。
要从您的情况中恢复,您应该创建一个分支,指向分离的头当前指向的提交:好的。
1 2 | git branch temp git checkout temp |
(这两个命令可以缩写为 这将使您的头重新连接到新的 接下来,您应该将当前提交(及其历史记录)与您期望在其上工作的正常分支进行比较:好的。 (您可能希望尝试使用日志选项:添加 如果您的新 (这两个命令可以缩写为 然后可以删除临时分支:好的。 最后,您可能希望推动重新建立的历史:好的。 如果远程分支不能"快速转发"到新的提交(即,您删除了一些现有的提交,或重写了一些现有的提交,或以其他方式重写了一些历史记录),则可能需要将 如果您正在执行一个重新平衡操作,您可能应该清理它。您可以通过查找目录 只要这样做: 或者,如果您有要保留的更改,请执行以下操作:
2
3
git diff master temp
git diff origin/master temp
2
git checkout master
1 2 | git checkout -b temp git checkout -B master temp |
我遇到了这个问题,当我读到最热门的答案时:
HEAD is the symbolic name for the currently checked out commit.
我想:啊哈!如果
1 | git rebase HEAD master |
这个命令:
最终结果是,所有在
关于遥控器:
a couple of the commits I'd killed in the rebase got pushed, and the new ones committed locally aren't there.
无法再使用本地历史记录快速转发远程历史记录。您需要强制push(
当您将
请查看此处了解分离头的基本说明:
网址:http://git-scm.com/docs/git-checkout
可视化命令行:
1 | git branch |
或
1 | git branch -a |
您将得到如下输出:
1 2 3 | * (no branch) master branch1 |
您可以通过执行
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
现在,要让他们成为大师:
做一个
1 | git merge HEAD@{1} |
编辑:
要添加,使用
把你的独立承诺放到它自己的分支上
只需运行
然后运行
如果您只有主分支并且想要返回到"开发"或某个特性,那么只需执行以下操作:
1 | git checkout origin/develop |
注:检查来源/发展。
你处于超然状态。你可以四处看看,做实验更改并提交它们,您可以放弃在此过程中所做的任何提交。通过执行另一个签出而不影响任何分支的状态…
然后
1 | git checkout -b develop |
它的工作原理是:
如果要推动当前分离的头部(之前检查
1 | git push origin HEAD:master |
把你的超支头送到原点的总支。如果您的推送被拒绝,请先尝试
要在保留更改的同时返回主分支,请尝试以下命令:
1 2 | git rebase HEAD master git checkout master |
请参见:git:"目前不在任何分支上。"是否有一种简单的方法可以在保留更改的同时回到分支上?
我今天刚遇到这个问题,我确信我通过以下方式解决了它:
1 2 3 | git branch temp git checkout master git merge temp |
我在工作电脑上找到了解决方法,现在我在个人电脑上遇到了同样的问题。所以我必须等到星期一,当我回到工作电脑,看看我是如何做到的。
以下内容适用于我(仅使用分支主机):
1 2 3 | git push origin HEAD:master git checkout master git pull |
第一个将分离的头部推到远程原点。
第二个移动到分支主机。
第三个恢复连接到分支主机的头。
如果推送被拒绝,第一个命令可能会出现问题。但这将不再是分离式头部的问题,而是关于分离式头部不知道某些远程变化的事实。
如果你完全确信头部是良好的状态:
1 2 | git branch -f master HEAD git checkout master |
你可能不能推到原点,因为你的主人已经偏离了原点。如果您确定没有其他人使用回购,您可以强制推动:
1 | git push -f |
如果您在一个其他人都不使用的功能分支上,则最有用。
正如克里斯所指出的,我有以下情况
然而,
在那之后我做了很多乱七八糟的事情,但似乎已经解决了,
头被重新连接!
您所要做的就是"git checkout[branch name]",其中[branch name]是您进入分离头状态的原始分支的名称。(与asdfasdf分离)将消失。
例如,在分支"dev"中,您签出提交asdfasd14314->
1 | 'git checkout asdfasd14314' |
你现在处于超然状态
"git branch"将列出类似->
1 2 3 4 | * (detached from asdfasdf) dev prod stage |
但要离开分离的头部状态并返回到dev->
1 | 'git checkout dev' |
然后"git branch"将列出->
1 2 3 | * dev prod stage |
当然,如果您不打算保留脱离头部状态的任何更改,但我发现自己这样做并不是为了进行任何更改,而是为了查看以前的提交
我今天遇到了这个问题,我更新了一个子模块,但没有任何分支。我已经承诺过了,所以藏匿、结帐、解冻都不起作用。我最后谢丽接受了超然的首长的承诺。因此,在我承诺(当推送失败时)之后,我立即做到了:
1 2 | git checkout master git cherry-pick 99fe23ab |
我的想法是:我是一个超然的人,但我想成为主人。假设我的分离状态和主没有太大的不同,如果我能将我的承诺应用到主,我就可以被设置。这正是Cherry Pick所做的。
而不是做
就这么做吧。
那么,
我在搜索
在分析了我为到达这里所做的一切之后,与我过去所做的相比,我发现我犯了一个错误。
我的正常流量是:
1 2 3 4 | git checkout master git fetch git checkout my-cool-branch git pull |
这次我做到了:
1 2 3 4 | git checkout master git fetch git checkout origin/my-cool-branch # You are in 'detached HEAD' state. |
问题是我不小心做到了:
1 | git checkout origin/my-cool-branch |
而不是:
1 | git checkout my-cool-branch |
修复方法(在我的情况下)只是运行上述命令,然后继续流:
1 2 | git checkout my-cool-branch git pull |
如果你在master上面做了一些承诺,只是想"向后合并"
1 | git checkout -B master HEAD |
我发现这在子存储库的情况下特别有用,而子存储库恰好也经常处于分离状态。
对我来说,这就像再次删除本地分支一样简单,因为我没有任何要推动的本地提交:
所以我做到了:
1 | git branch -d branchname |
然后再次检查分支:
1 | git checkout branchname |
我有同样的问题,我通过以下步骤解决了它。
如果您需要保留更改
如果你不需要零钱
要从分支中删除所有未跟踪的文件,请运行
然后,您需要清除存储库中所有未分页的更改。为了做到这一点,你必须运行
最后,您必须使用
简单来说,分离的头状态意味着您没有签出到任何分支的头(或尖端)。
以身作则大多数情况下,分支是多个提交的序列,例如:
承诺1:主管——>分行主管(123BE6A76168ACA712EA16076E971C23835F8CA)
承诺2:Master——>123BE6A76168ACA712EA16076E971C23835F8CA——>分支头(100644A76168ACA712EA16076E971C23835F8CA)
正如上面在提交序列的情况下看到的,您的分支指向最新的提交。因此,在这种情况下,如果您签出以提交123BE6A76168ACA712EA16076E971C23835F8CA,那么您将处于独立的头状态,因为您的分支机构负责人指向100644A76168ACA712EA16076E971C23835F8CA,并且从技术上讲,您是在没有分支机构的负责人签出的。因此,您处于分离的头部状态。
理论解释在这个博客里,它清楚地表明Git存储库是一个提交树,每次提交都指向其祖先,每次提交指针都会更新,指向每个分支的这些指针存储在.git/refs子目录中。标记存储在.git/refs/tags中,分支存储在.git/refs/heads中。如果您查看任何一个文件,就会发现每个标记对应于一个单独的文件,具有40个字符的提交哈希,正如上面由@chris johnsen和@yaroslav nikitenko解释的那样,您可以查看这些引用。
当我发现自己处于这样一种情况时,当我发现自己在不在
1 2 3 | 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 2 3 4 | git ls-remote origin 0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b HEAD 6f96ad0f97ee832ee16007d865aac9af847c1ef6 refs/heads/HEAD 0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b refs/heads/master |
我最终解决了这个问题
1 | git push origin :HEAD |
如果在Eclipse中使用eGit:假设你的主人是你的主要发展部门
- 将更改提交到分支,通常是新的分支
- 然后从遥控器中拔出
- 然后右键单击项目节点,选择团队,然后选择显示历史记录。
- 然后右键单击主控形状,选择"签出"
- 如果Eclipse告诉您,有两个主控形状,一个本地,一个远程,请选择远程
在这之后,您应该能够重新连接到源站主服务器。
在我的例子中,我运行了
为了使钢筋工作,我只需要清理它们(因为我不需要它们)。
这对我很有效:
1.
如果要放弃更改
2.
1 2 | On branch master Your branch is up-to-date with 'origin/master'. |
我也有同样的问题。我把零钱存起来
1 2 3 | 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 |