GIT restore last detached HEAD

Please, I have a big problem in my project: this is the scenario. I have an xcode project under GIT. Today I realized that the last commit broke some tests, so i checked out the previous commit. I used SourceTree and this is the warning

Doing so will make your working copy a 'detached HEAD', which means you won't be on a branch anymore. If you want to commit after this you'll probably want to either checkout a branch again, or create a new branch. Is this ok?

I worked for an entire day and at the end I committed everything. So I needed to merge my work on develop branch so I checkout the develop branch and...my work instantly disappeared :(

I know it was wrong to detach my HEAD and Sourcetree warned me...but there is a way to restore my work?


Solution 1:

If you type git reflog, it will show you the history of what revisions HEAD pointed to. Your detached head should be in there. Once you find it, do git checkout -b my-new-branch abc123 or git branch my-new-branch abc123 (where abc123 is the SHA-1 of the detached HEAD) to create a new branch that points to your detached head. Now you can merge that branch at your leisure.

Generally, if you check out a branch after working on a detached head, Git should tell you the commit from the detached head you had been on, so you can recover it if you need. I've never used SourceTree, so I don't know if it relays that message. But if it did display that message, then you should be able to use that to find the commit, and again use git checkout -b or git branch to create a branch from that commit.

Solution 2:

In Sourcetree, you can do this using the GUI.

First find the "lost" commit by looking for a message in the Command History (view:Show Command Output). It will probably be in the command "Switching Branch" after the commit that you lost. In that message, hopefully you'll see the commit comment with a 1234567 commit ID.

Take that Commit ID to next step.

Hit the "Branch" button in the top toolbar and you should get a dialog "New Branch" where you can specify a certain commit. Put that Commit ID in there, specify a new branch name, hit Create Branch and you should get a new branch with your lost commit!

enter image description here

Solution 3:

If you dont want to keep changes of detached HEAD and want to go to latest branch commit use below command directly.

git checkout - 

Note:I will delete all your changes in the detached HEAD.

Solution 4:

  1. First, run git reflog to view history.
  2. The oldest revision will be the last one in the list.
  3. Switch to your desired commit using git checkout -b temp e35d2b3 here e35dd23 is the hash value of your commit.
  4. That's it. Now just do git add . etc....

Accept it as an answer if it solves your issue. Otherwise please share your comment.

Solution 5:

A colleague of mine just had this situation. In his case, there were commits in detached head --they work in R-Studio-- and the tool did warn them that they could create the branch with this and that SHA reference... but since the only option was "Close" --duh!! it was a info box-- they closed the dialogue and lost the info for ever...

Thanks to the reflog command we could see that the changes were not lost. But in our case, the git branch did not work as expected... or a incoming git pull did mess it up somehow. We had to fish the changes from the reflog to the newly created branch:

 git cherry-pick 0b823d42..3cce27fc

which placed all the commits we wanted in the branch. Then we could merge the branch into develop without issues.

Just in case this is informative for anyone, we did identify the commits on detached head in the reflog by looking at those in between the marked with "checkout" (which identify branch shifting):

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

Those we wanted were HEAD@{8} to HEAD@{6} (both inclusive). So we got them by:

git cherry-pick 0b823d42..3cce27fc

Then the usual merge solving and final commit left us with branch lost_changes hosting the detached-head work that we thought lost. Merging that into develop was fast-forward this time.