如何改变HEAD的领先优势?

时间:2012-02-03 01:06:43

标签: git

我有很多变化,只是,噗,从树上消失了。或者它们似乎在某种程度上正在树上方盘旋......

例如,我有一个文件scripts/skin.prestitial.supp.js我做了一个小改动,提交是e48c156。

 git log scripts/skin.prestitial.supp.js

给了我

 commit bdf9ceda54e0cfc528f0618c6d47c0399cf956b0
 Author: David <david@company.com>
 Date:   Wed Feb 1 18:16:56 2012 -0800

     SV-865 - chat change prestitial

 commit f218dd99c42aeaa754a14644c951adde41a0b58c
 Author: David <david@company.com>
 Date:   Mon Jan 30 18:43:19 2012 -0800

     sv-753 how this works lb

依此类推,没有e48c156。它完全消失了。我喜欢“哦,不!”,然后我尝试了这个:

 git log e48c156 scripts/skin.prestitial.supp.js

给出

 commit e48c1569f05481e269d7bfcd73547b2ec226e777
 Author: Michael <info@company.com>
 Date:   Wed Feb 1 19:50:48 2012 -0800

     SV-861  Add "Done" to "how it works" lightbox

 commit bdf9ceda54e0cfc528f0618c6d47c0399cf956b0
 Author: David <david@company.com>
 Date:   Wed Feb 1 18:16:56 2012 -0800

     SV-865 - chat change prestitial

 commit f218dd99c42aeaa754a14644c951adde41a0b58c
 Author: David <david@company.com>
 Date:   Mon Jan 30 18:43:19 2012 -0800

     sv-753 how this works lb

即,改变是在当前HEAD“之上”或“之后”。我是怎么做到的?如何找到“现在”前面的所有其他更改?我该如何取回它们?我如何防止这种情况再次发生?

3 个答案:

答案 0 :(得分:3)

首先,请不要责怪Git。无论你怎么想,你都做了一些事情,导致不再能从HEAD获得提交,并且暗示它不受你的控制,只能让你无法弄清楚它是什么,如何解决它,以及如何避免它。

它可以是任意数量的东西:重置为先前的提交(git reset),检出先前的提交或前一次提交的分支(git checkout),进行rebase和删除提交(git rebase -i),修改具有不同内容(git commit --amend)的提交...

请注意,由于你的问题是如此模糊,有很多可能性,我试图涵盖我所想到的所有可能的问题,但我不一定会想到一切。如果您不理解,或者没有证实他们是正确的做法,请不要盲目地遵循指示。 (例如,你的问题并没有真正证明你提交了HEAD的提前;他们可能会与它分道扬。)

您可能想要做两件事:看看HEAD的当前位置与您认为应该在哪里相关,并看看您是如何移动的。

要查看当前的历史状况,有一些有用的东西:

  • 通过运行git branch甚至git status,查看您是否在您认为应该在的分支机构上。如果您只是检查了错误的分支,那么您现在可能已经完成了 - 只需查看正确的内容即可。如果您已经分离了HEAD(即没有检出分支),您将要检查正确的分支,然后如果您在HEAD分离时进行了提交,请合并这些提交。
  • 查看历史记录,最好使用gitk --branches e48c156,以确保它显示所有分支和您关心的提交。如果您对此感到满意,也可以使用git log [--decorate] [--graph] ...,但gitk更擅长直观地显示大量复杂的历史记录。

您应该能够看到当前签出的分支/提交与您认为应该在哪里相关。

要了解您的所作所为,最有用的工具是git reflog。这列出了HEAD的先前位置。它将按相反的时间顺序列出HEAD的所有先前位置,以及导致每次移动的操作的摘要。可能与gitk组合以查看提交的位置,您应该能够找到您所做的事情。 (您也可以使用git reflog show <branch>在分支上使用它。)如果您想要的实际提交是过去 e48c156,这将是发现它的方法。

当你找到自己想要的地方时,你可以回到原点。在大多数情况下,这就像git merge <desired-commit>一样简单。如果你搬回来之后还没有提交,那么它将是一个快速合并,只会让你前进,如果你有,那将是一个非常重要的合并,它应该能得到你想要的东西。如果您有本地修改,您可能需要先将它们存起来。但是,如果问题是你做了一个rebase或修改了一个提交,并删除了你想要的那个,你需要更加小心 - 很可能创建一个分支,其中事情在错误之前,并合并/ rebase /樱桃挑选了之后的变化。

作为最后的手段,还有git fsck,它将打印一个列表,列出当前引用无法访问的所有对象。你会想要寻找悬空提交;然后,您可以使用您最熟悉的任何工具来确定它们是否是您关心的事物。但这不应该是必要的;最糟糕的情况是,事情都在reflog中。

至于如何再次避免这种情况发生,好吧,弄清楚你做错了什么,不要再做了。如果它涉及检查错误的东西,您可以考虑修改您的提示以包括当前分支名称(和其他有用的东西):

export PS1="...$(__git_ps1 "(%s)")..."

答案 1 :(得分:1)

不确定你是如何做到这一点的(尽管简单的git reset --hard HEAD~1会产生相同的行为)。

与Mercurial等其他分布式版本控制系统不同,Git的工作原理是删除提交的链接,而不是提交本身。 (就像删除文件一样。)

您可能会发现git fsck --lost-found对于查找其他悬空提交非常有用。

答案 2 :(得分:0)

这可能太明显了,但是你确定你不是偶然检查了之前的提交吗?从您的历史记录中,它看起来像您提交的,然后更改您的索引以代表前一个头:

(previous commits) <-- f218dd9 <-- bdf9ced <-- e48c1569
                                      ^--you

只需运行git branchgit status即可告诉您正在使用的分支和提交内容,而git log应该告诉您在历史记录中的位置。考虑从当前位置创建一个新分支 - git checkout -b new branch HEAD - 然后切换到master的顶部并查看其外观。