我有很多变化,只是,噗,从树上消失了。或者它们似乎在某种程度上正在树上方盘旋......
例如,我有一个文件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“之上”或“之后”。我是怎么做到的?如何找到“现在”前面的所有其他更改?我该如何取回它们?我如何防止这种情况再次发生?
答案 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 branch
或git status
即可告诉您正在使用的分支和提交内容,而git log
应该告诉您在历史记录中的位置。考虑从当前位置创建一个新分支 - git checkout -b new branch HEAD
- 然后切换到master
的顶部并查看其外观。