Search code examples
gitgithubsavecommitgit-commit

Urgent Git help needed - lost most commits


So I was working on a project and early on I accidentally detached from the Head, but I still kept commit etc. anyway. I then realized I was detached from the head, so I tried to do the following to reattach to the head:

git log -n 1 (I copied the commit)

git checkout master

git branch (long hash I copied)

git merge tmp (here I realize I forgot to name the branch so I typed again:

git branch tmp (long has I copied)

i got a warning here about how the rename (long hash) is ambiguous, and Git normally never creates a ref that ends with 40 hex characters

git merge tmp

here git said "already up to date"

git branch -d tmp

output: deleted branch tmp

after doing this, I was taken back to the state in which I was last attached to the head (wayyy back in my project).

Am I screwed? Or is there any way I can recover where I was at?


Solution

  • First off, you are not screwed. When you are in weird situations like this it is always good to make a full backup (including the hidden folders) before attempting to fix it, in case you mess up.

    git reflog is your friend, it shows you the hashes of commits you have done in the past. In your case you have checked out the master and then created a branch from master with the name being the hash of the last commit in your detached head. This in turn makes it hard to git checkout that commit because when you enter the hash of the commit git assumes you mean the branch with the same name.

    I tried to re create your situation and came up with a step by step plan to recover your lost code: (only attempt after making a full backup)

    1. git reflog find the hash of the commit you want to recover (most likely in the format of i.e. "47a7bdc (HEAD -> master, 7a1.....5b7) HEAD@{3}: commit: 2" )
    2. git branch -d <"long hash you copied"> which will also probably be the hash you found in reflog
    3. git checkout <the hash of the commit you want to recover>

    At this point you have the state of your last commit on the detached head.

    1. git branch tmp <the hash of the commit you want to recover> to really create the tmp branch with your detached commits, like you presumably intended
    2. git checkout master to get back to your master branch, as creating a new branch automatically changes to it
    3. git merge tmp to merge the just created tmp branch back on to the master branch

    At this point git might complain about merge conflicts, if so - you have to resolve these manually and then create a new commti for that merge.

    Additional hints:

    • allways check with git status in what state you are
    • use git log --graph --oneline --all to get a visual reference
    • i've heared that some git GUIs delete the reflog information, to avoid these problems a) only use CLI b) allways make full backups in situations when you are not fully sure what you are doing