GIT恢复上一个分离的HEAD


85

拜托,我的项目有一个大问题:这就是场景。我在GIT下有一个xcode项目。今天,我意识到上一次提交破坏了一些测试,因此我签出了上一次提交。我使用了SourceTree,这是警告

这样做将使您的工作副本成为“分离的HEAD”,这意味着您将不再位于分支上。如果您想在此之后提交,则可能要再次签出一个分支,或创建一个新分支。这个可以吗?

我工作了一整天,最后我付出了一切。所以我需要合并我在develop分支上的工作,所以我检出develop分支,然后...我的工作立即消失了:(

我知道分离HEAD是错误的,并且Sourcetree警告我...但是有办法恢复我的工作吗?


对于同样的问题,与此相关的线程在这里和它是如何发生的技术性这里
RBT

Answers:


254

如果输入git reflog,它将显示修订HEAD指向的历史记录。你的头顶应该在那儿。找到它后,请执行git checkout -b my-new-branch abc123git branch my-new-branch abc123abc123分离的HEAD的SHA-1在哪里)以创建一个指向您的分离的头的新分支。现在,您可以随意合并该分支。

通常,如果您在处理分离头后签出分支,Git应该告诉您先前使用的分离头的提交,以便您可以根据需要进行恢复。我从未使用过SourceTree,所以我不知道它是否中继该消息。但是,如果确实显示了该消息,那么您应该能够使用它来查找提交,然后再次使用git checkout -bgit branch从该提交中创建分支。


4
谢谢布莱恩。你救了我的日子。
Muzammil

布莱恩,你救了我的命!谢谢!!
cldrr 2014年

我是git的新手。我正在获取fatal: A branch named 'mybranch' already exists.如何在现有分支中添加?
Ramesh Murugesan 2015年

1
作为对所有感谢Brian的人的PSA:如果您正在做自己不想丢失的工作,请每隔几个小时将其推送到远程(例如github)。当流星落在计算机上时,您会很高兴的。如果您尚未准备好与协作者共享它,只需将其放在一个暂时不为人所知的分支中,然后再将其重新建立为master。
MatrixManAtYrService

1
另外,如果只是一个丢失的提交而已消失,而您在此处找到了它,则可以使用来将其恢复git cherry-pick e5b2f7b,那里e5b2f7b的提交的SHA-1在哪里。
艾丁

10

在Sourcetree中,可以使用GUI进行此操作。

首先通过在命令历史记录中查找一条消息来找到“丢失的”提交(视图:显示命令输出)。丢失的提交后,可能会在命令“ Switching Branch”中。希望在该消息中,您将看到带有1234567提交ID的提交注释。

将该提交ID转到下一步。

点击顶部工具栏中的“分支”按钮,您将获得一个“新分支”对话框,您可以在其中指定某个提交。在其中放置该Commit ID,指定一个新的分支名称,点击Create Branch,您将获得一个新的分支,其中包含丢失的提交!

在此处输入图片说明


实际有效。确保您看到带有提交ID的正确注释。
哈马德·汗

@blalond您好,在阅读完您的答案后,我有一个小问题:在SourceTree中,我双击上一个提交(以将其检出)时,得到的消息是,这将导致头部分离,所以我想知道当人们说您可以使用git简单地回滚到任何以前的版本时,这意味着什么?那我该如何回滚到特定的提交?谢谢

5

如果您不想保留分离的HEAD的更改,并且想要直接转到最新的分支提交,请直接使用以下命令。

git checkout - 

注意:我将在分离的HEAD中删除所有更改。


OP确实要求保留其工作。这不能回答原始问题。只需添加将其保留在分支中的选项,此答案将非常有用。
manuelvigarcia,

1

我的一位同事遇到了这种情况。在他的案例中,有分离的头部提交(他们在R-Studio中工作),并且该工具确实警告他们可以使用该引用和SHA引用创建分支……但是由于唯一的选择是“ Close” --du!这是一个信息框-他们关闭了对话,并永远丢失了信息...

借助reflog命令,我们可以看到所做的更改没有丢失。但是在我们的情况下,git branch不能按预期工作...或传入git pull确实以某种方式使其混乱。我们必须将更改从reflog转移到新创建的分支:

 git cherry-pick 0b823d42..3cce27fc

它将所有我们想要的提交放置在分支中。然后,我们可以将分支合并到develop没有问题的地方。

以防万一,这对任何人都有用,我们通过查看标记为“ checkout”(标识分支转移)之间的提交,确实确定了分离头中的提交reflog

e09f183b HEAD@{3}: pull: Fast-forward
b5bf3e1d HEAD@{4}: checkout: moving from lost_changes to develop
b5bf3e1d HEAD@{5}: checkout: moving from 3cce27fca50177a288df0252f02edd5da5ee64fd to lost_changes
3cce27fc HEAD@{6}: commit: add statistics
417a99a4 HEAD@{7}: commit: add test
0b823d42 HEAD@{8}: commit: new utility class
d9ea8a63 HEAD@{9}: checkout: moving from develop to d9ea8a635d4c2349fcb05b3339a6d7fad5ae2a09
b5bf3e1d HEAD@{10}: pull: Fast-forward

那些我们需要做的是HEAD@{8}HEAD@{6}(包括两端)。因此,我们通过以下方式获得它们:

git cherry-pick 0b823d42..3cce27fc

然后,通常的合并解决方案和最终提交给我们留下了Lost_changes分支,托管我们认为丢失的独立工作。这次,将其合并为开发是快速的。


0

我尝试了这种情况,发现git告诉我SHA-1的最后一次提交:

vors@localhost:~/git-test$ git checkout master 
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  ec600e6 333

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch new_branch_name ec600e6eb2473dd4f3732539c5c1fa5829f631b7

Switched to branch 'master'

您看到此消息了吗?


没有。也许我不注意。我正在寻找timemachine的备份;(
IgnazioC

1
@IgnazioC您无需查看备份。你看看我的回答了吗?git reflog应该告诉你你需要什么。
布莱恩·坎贝尔

0

只要您不作任何改变,超脱的头就可以了。

如果要还原提交,可以在特定分支上使用git revert

如果您想解决超脱的头脑并进行提交;创建一个新分支(然后合并它);


是的 我们确实知道规则。但是,当同事们努力工作,然后放弃这些承诺时,他们会寻求答案,而不是规则。
manuelvigarcia,

0
  1. 首先,运行git reflog以查看历史记录。
  2. 最旧的修订版将是列表中的最后一个。
  3. 使用git checkout -b temp e35d2b3此处切换到所需的提交,e35dd23是提交的哈希值。
  4. 而已。现在只需执行git add即可。等等....

如果可以解决您的问题,请接受它作为答案。否则,请分享您的评论。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.