Git:HEAD已经消失了,想把它合并成主人

时间:2010-03-25 20:15:21

标签: git

reflog vs GITK http://siteroller.net/archive/images/Forums/headless%20GIT.png

顶部图像是输出:git reflog。
底部是GIT GUI(msysgit)中的GITK在查看所有分支历史时向我显示的内容。

最后几次提交没有在GIT GUI上显示。

  • 为什么他们不在GITK上展示(至少作为一个分支或什么)?
  • 如何将它们合并为主?
  • 当我检查标签0.42时,我收集了这个。为什么和主人不一样? (我在最新状态下标记了主人)
  • 当我点击推送时,为什么远程仓库声称是最新的...它不应该尝试将这些提交更新为它们所在的任何分支吗?

第一个问题很重要 - 我想开始了解GIT的想法。在这一点上,它比逻辑更具神谕性。

如果看到之前的历史记录有所不同,那么该项目是一个[非常强大的] JS颜色选择器,整体上可以viewed here

3 个答案:

答案 0 :(得分:11)

  

为什么要将这些提交更新为它们所在的分支?

就是这样:您不在任何分支机构,但目前正在开展 detached head

  

从版本1.5.0开始,上面的命令将HEAD与当前分支分离,并直接指向标记所指定的提交。

如果您执行gitk --all

,可能会看到它

解决问题的一种方法(如果你已经提交了所有内容)

$ git log -1
# note the SHA-1 of latest commit
$ git checkout master
# reset your branch head to your previously detached commit
$ git reset --hard <commit-id>

另一种方法是将你的工作合并到恰好位于标签的当前主HEAD:

 $ git checkout -m 0.42

但是这会丢失你在一个独立的HEAD上做出的提交的历史。


  

当我检查标签0.42时,我收集了这个。为什么和主人不一样? (我在最新状态下标记了主人)

不,它与主人不一样。正如Jefromi在评论中指出的那样,分支可以移动(或重命名,删除,或......) master指的是与'0.42'标签相同的提交,但情况并非总是如此 签出标签后,您不会签出分支,因此处于“分离的HEAD”状态。


注意:如this SO answer中所述,您看到的@{1}表示法是$(git symbolic-ref HEAD)@{1},即它使用reflog作为当前(此处为分离的)分支,而不是HEAD reflog。

答案 1 :(得分:3)

在Git中,提交形成一个有向无环图,其中每个提交指向一个或多个父提交。除了提交对象,您还有ref(即引用)对象:分支和标记。它们指向提交图中的各种提交。您的问题是,当您提交提交并且没有分支(或标记)指向它们时,您不在分支上。您可以随时使用命令

git status

git branch

检查你是否在分支机构。

  

为什么他们没有在GITK上展示(至少作为一个分支或什么)?

据我所知,Gitk从refs开始查找提交对象。如果没有ref指向你的提交(或导致它们的提交的有向非循环图),它们实际上是不可见的。

  

如何将它们合并为主?

幸运的是,reflog工具跟踪结账和提交等操作(以及其他内容)。在您的reflog列表中,您可以看到上次提交的条目:

  

1b8c11d HEAD @ {1}提交:缩短为RM()函数

您应该能够使用您在reflog中看到的SHA1 ID将提交合并到主分支:

git checkout master
git merge 1b8c11d
  

当我检查标签0.42时,我收集了这个。为什么和主人不一样? (我在最新状态下标记了主人)

分支和标记之间的主要区别在于标记始终指向相同的提交但分支向前移动。例如,如果您在分支“master”上并进行新的提交,则“master”分支向前移动并开始指向刚刚创建的新提交。当你签出提交,标签或分支时,Git会完全按照你的命令检查你的命令。

  

当我点击推送时,为什么远程仓库声称是最新的...它不应该尝试将这些提交更新为它们所在的任何分支吗?

您的提交不在任何分支上。您首先需要将它们合并到分支(例如,到master),如上所示。在此之后,推动应该正常工作。

答案 2 :(得分:2)

恢复提交的最简单方法是将一些分支指向它们。你知道SHA,所以很容易:

git branch resurrected_junk 1b8c11d

(这是从你的截图中读取的SHA),也可以是

git branch resurrected_junk HEAD@1

这将指向最近的丢失提交的分支 - 较早的可能是最近的提交的父母,所以他们将在这个新的分支上;如果它们不存在(这意味着丢失提交有两个“影子分支”),则必须检查所有提交并重申缺少提交的过程。

在你的情况下,我猜你会得到这样的历史记录:

Master --> Optimize toRGB --> ... ---> shortened toRGB = resurrected_junk

然后,刷新你的gitk视图,提交应该出现。 (我正在使用qgit,所以我只是在猜测)

之后,你应该能够合并/推送/任何想要的东西(如你所愿)。