Git:HEAD已经消失,想要将其合并到主分支。

7

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

上方的图片是git reflog命令的输出结果。
下方的图片是在GIT GUI(msysgit)中查看所有分支历史时显示的内容。

GIT GUI中并没有显示最近几次提交记录。

  • 它们为何不会在GITK中显示(至少作为一个分支或其他形式)?
  • 如何将它们合并到主分支(master)中?
  • 当我检出标签0.42时,为什么它和主分支不同(我的意思是,我已经将主分支打了一个标签,其表示最新状态)?
  • 当我点击推送按钮时,为什么远程仓库会声称是最新的.. 它不应该尝试将这些提交更新到与之相关的分支吗?

第一个问题很重要 - 我想开始了解GIT在想什么。它现在更像是个神谕而非逻辑。

如果查看之前的历史记录对了解情况有所帮助,那么这个项目是一个[非常强大的]JS颜色选择器,可以在此处完整查看。


图片已经损坏(因此无用),您能否将图片放在新位置或包含我们应该看到的ASCII版本? - George Stocker
3个回答

12
这就是问题所在:你没有在任何分支上工作,而是目前正在使用一个分离头部

 

从版本1.5.0开始,上述命令将使你的HEAD与当前分支分离,并直接指向由标签命名的提交。

如果你已经提交了所有内容,可以通过以下方法之一来修复它:

$ 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时,我明白发生了什么。为什么它与master不同?(我已经将master标记为最新状态)

不,它不同于master。正如Jefromi在评论中指出的那样,分支可能会移动(或重命名、删除等等)。
master引用的是与'0.42'标签相同的提交,但并非始终如此。
使用标签进行检出时,您不会检出分支,因此会处于“分离 HEAD”状态。


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


澄清:您检出了指向特定提交的标签。它不指向分支。(它不能-分支可能会移动!)分支和标签现在恰好处于同一位置。但是,您检出了标签,因此git检出了该提交并分离了您的HEAD。 - Cascabel
@Jefromi:我仍在编辑答案,最新的一次编辑提到了你的澄清;) - VonC
因为我检出到了一个标签 - 可能会移动 - 然后开始更改内容,所以我现在处于分离头状态。分离头不是一个分支,因此不会显示或远程更新。我明白了,尽管我仍然不明白为什么不行 [尽管您在另一个线程中的评论]。 我不理解合并说明。我已经切换回主分支,并知道提交的 SHA(请参见 reflog 图像)。那么,现在我只需要重置 --hard 吗?如果是这样,重置到哪个提交 ID.. b88fd04? - SamGoody
@samgoody:标签从不移动,这就是标签的全部意义。分支会移动(它们只是指向分支HEAD的指针)。在您的情况下,您确实需要重置到提交“b88fd04”,因为这将使主HEAD移动到该提交,从而使所有在分离的分支上进行的提交成为主分支的一部分。 - VonC

3

在Git中,提交形成了一个有向无环图,每个提交都指向一个或多个父提交。除了提交对象外,还有ref(即引用)对象:分支和标签。它们指向提交图中的各种提交。你的问题是,在进行提交时,你没有处于任何分支上,也没有分支(或标签)指向它们。您可以随时使用以下命令:

git status

并且

git branch

检查当前是否处于分支状态。

为什么它们不在GITK中显示(至少作为一个分支或类似的东西)?

据我所知,Gitk从refs开始查找提交对象。如果没有引用指向您的提交(或导致它们的有向无环图(DAG)),则它们有效地是不可见的。

如何将它们合并到主分支(master)中?

幸运的是,reflog工具可以跟踪像检出和提交等操作(以及其他一些事情)。在您的reflog列表中,您可以看到最后一次提交的条目:

1b8c11d HEAD@{1} commit: Shortened toRgb() function

您可以使用在reflog中看到的SHA1 ID, 将这些提交合并到您的主分支(master).

git checkout master
git merge 1b8c11d

我看到这个问题是在我检出标签0.42时发生的。为什么这与主分支不同?(我已经将主分支标记为最新状态)
分支和标签的主要区别在于,标签始终指向相同的提交,而分支会向前移动。例如,如果您在“主”分支上并创建了一个新提交,则“主”分支将向前移动并开始指向您刚刚创建的新提交。当您检出提交、标签或分支时,Git会完全按照您的命令进行操作,并检出您所要求的内容。
当我点击推送按钮时,为什么远程存储库声称已经是最新的..它不应该尝试将这些提交更新到它们所在的任何分支中吗?
您的提交不属于任何分支。您需要首先像上面显示的那样将它们合并到一个分支(例如主分支)中。之后,推送应该正常工作。

我结合使用了git log -1来执行这个操作。 - Andy Fleming

2
最简单的恢复提交的方法是将某个分支指向它们。你知道SHA值,所以很容易:
git branch resurrected_junk 1b8c11d

(这是从您的截图中读取的SHA),也可以是:
git branch resurrected_junk HEAD@1

这将把一个分支指向您丢失的提交中最新的那个——早期的提交可能是最近提交的父提交,因此它们将在这个新分支上;如果它们不在(这意味着有两个“丢失提交”的“影子分支”),则您需要查看所有提交并为缺失的提交重复该过程。
在您的情况下,我猜您会得到这样的历史记录:
Master --> Optimize toRGB --> ... ---> shortened toRGB = resurrected_junk

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

之后,你应该可以像你喜欢的那样合并/推送/任何你想要的操作。


请更加详细地说明 - 我不明白。我应该将resurrected_junk提交到哪个提交中?是我分离的提交中最早的,最新的还是所有的提交中?另外,“could be also”是什么意思?如果我执行git branch resurrected_junk HEAD@1,那么我是否可以在需要的master分支中获得所有内容?我会有两个分支,然后将它们合并在一起吗? - SamGoody
最新的提交;“也可能是”意味着HEAD@1在您的情况下只是1b8c11d的一个更方便的名称。它不会将您的提交放入主分支,而是会有另一个分支。如果您想要,您可以将其合并到主分支中;在您的情况下,这应该是一个简单的快进式合并。 - jpalecek

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