190

This is what happened:

I have a branch A. On branch A I committed a bunch of changes. I was not happy with the code, so I checked out the previous commit in branch A. I then made a bunch more changes and committed them on branch A. Now I can not find this commit anywhere. Did I lose this code?

Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
Mausimo
  • 8,018
  • 12
  • 52
  • 70
  • When you say "I checked out the previous commit in branch A", do you mean "I reset branch A to the previous commit"? i.e. did you actually `git reset` rather than `git checkout`? – CB Bailey Apr 02 '12 at 21:43
  • No, i used checkout. reflog worked. – Mausimo Apr 02 '12 at 21:50
  • If you used checkout then you will have been on a detached `HEAD` and branch A would have stayed on the previous commit. Exactly what commands did you run? – CB Bailey Apr 02 '12 at 22:13
  • 1
    I was using the SourceTree GIT GUI on OSX Lion. I Was on branch A and ran a checkout of the previous commit on Branch A. I then did a bunch of code changes and committed (Branch A). I believe I had a detached HEAD. – Mausimo Apr 02 '12 at 22:16
  • OK, I think I was confused when you said that you committed a bunch more changes _on branch A_. – CB Bailey Apr 02 '12 at 22:23

7 Answers7

266

The old commit is still in the reflog.

git reflog

This will show a list of commits, and the "lost" commit should be in there. You can make it into a new branch. For example, if the SHA-1 is ba5a739, then you can make a new branch named "new-branch" at the old commit with:

git branch new-branch ba5a739

Note that "lost" commits will get deleted when the database is pruned.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • 37
    Use `git cherry-pick [SHA]` to move the commit onto an existing branch in case you accidentally committed while in detached head state – Jan Aagaard Meier Aug 20 '14 at 12:56
  • 3
    Alternatively you can switch to an existing branch and do "git merge HEAD@{n}" n corresponding to the "lost" commit listed in reflog. – eaykin Jun 28 '16 at 14:35
  • Do you know if the `prune` would delete also detached commits that are being referenced in commit messages? Or that makes them *reachable*? – Kamafeather Jul 24 '18 at 08:42
  • 1
    @Kamafeather: I don't think that makes them reachable. – Dietrich Epp Jul 24 '18 at 14:10
  • I thought so. Meh... it would have been a nice feature in order to reference rewritten/lost trees (for reviewed pull requests, in my case) [Maybe I should open a feature request!]. Anyway, thank you. – Kamafeather Jul 24 '18 at 15:01
  • thanks for ur response, I want to know after making that commit to the new branch, we can merge this new branch to another branch safely? – Thamer Jul 26 '18 at 22:23
  • Once you create the branch, it is just an ordinary branch. Whether it merges safely is the same as for any other branch. – Dietrich Epp Jul 26 '18 at 22:24
95

Your commits are still available in the reflog, as pointed out already. In addition to the other answers, here is a way to take over the detached HEAD commits into your current branch directly, without creating and merging a new branch:

  1. Look up the SHA-1 hashes of the commits you made in detached HEAD state with

     git reflog
    
  2. Then execute, with all the commit hashes ordered from oldest to most recent:

     git cherry-pick <hash1> <hash2> <hash3> ...
    

    For example if I had only one, given in the "first 7 characters" short hash format:

     git cherry-pick a21d053
    

This will add new commits to your current branch, one commit per detached-HEAD commit that you mention in the command. It also takes over the original commit messages.

tanius
  • 14,003
  • 3
  • 51
  • 63
  • It's even easier to cherry-pick if you still have the hash, for instance it's still on your screen. So before you return from a detached HEAD, simply save the latest commit(s) you had, e.g., to a notepad. – Mykola Tetiuk Sep 02 '22 at 13:59
17

You may find lost (dangling) commits with the following command:

git fsck --lost-found

Note, if your current head is dangling commit, it is not listed as lost.

You may find more info at git-fsck(1) Manual Page

Then you may create branch on that lost commit:

git branch new-branch ba5a739
sergtk
  • 10,714
  • 15
  • 75
  • 130
11

Git parlance for the state of your working directory is a “detached HEAD.” Here is another place that git reflog makes the save.

$ git reflog
0b40dd6 HEAD@{0}: commit: my commit on detached HEAD
...

If I try to checkout a different branch, git-1.7.5.1 gives a helpful suggestion.

$ git checkout master
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  0b40dd6 my commit on detached HEAD

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 0b40dd65c06bb215327863c2ca10fdb4f904215b

Switched to branch 'master'
miva2
  • 2,111
  • 25
  • 34
Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
9

Follow these steps to link your detached head back to git repo

  1. git checkout "your branch with path but without remote name"

e.g. if remote name is origin and branch name is bugfix/somebranch then use git checkout bugfix/somebranch

  1. git reflog get the commit SHA's listed from your commit list of detached branch.

  2. git cherry-pick "commit hash1" "commit hash2" "commit hash3"

  3. git push

ALL SET!!

Dario
  • 3,905
  • 2
  • 13
  • 27
user1520615
  • 91
  • 1
  • 2
9

You did not lose it, Git still keeps a copy (but it is currently unreachable by any branch head). You can find your missing commit using the git reflog command. The reflog keeps track of the historical positions of a branch head, and you can use it to find things that the branch head was pointing at previously.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
2

In Sourcetree, I found that git reflog didn't work, so I figured out how to do this using the GUI.

First, try to find the "lost" commit by looking for a message in the Command History (view:Show Command Output). It'll hopefully be in the command "Switching Branch" after the commit that you lost and 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!

This brought back some lost work for me!

blalond
  • 875
  • 10
  • 17