Umair Jameel
Umair Jameel

Reputation: 1673

Accidentally ran command checkout -B "branchname" in git

I needed to commit and push my code. but in git extension, while trying to push the code, i got an error and I accidentally click on a button and my code gone. I went to git extension log and check the commands executed. checkout -B "mybranch" was executed. Now my whole code is gone. How to get it back?

edit: my logs after running git reflog enter image description here

Upvotes: 3

Views: 200

Answers (2)

torek
torek

Reputation: 487755

OK, the first step is to relax a bit: as long as you did run git commit, your code is not gone!

What git checkout -B branchname does is to create or re-set the given branchname. Given what else you have mentioned, I believe you actually ran git checkout -B UIUpdates origin/UIUpdates, which (for multiple intertwined reasons) ultimately had the effect of doing git reset --hard UIUpdates.

Based on what's in your reflog (in the edit):

ec1226b HEAD@{0}: checkout: moving from UIUpdates to UIUpdates
...
ec1226b HEAD@{5}: branch: Reset to origin/UIUpdates
5fc98bc HEAD@{6}: commit: issues and questions templates.
ec1226b HEAD@{7}: checkout: moving from UIUpdates to UIUpdates
ec1226b HEAD@{8}: branch: Reset to origin/UIUpdates
9a4c4ef HEAD@{9}: checkout: moving from UIUpdates to UIUpdates
...

it looks as though your own commit(s) are probably reachable from hash ID 5fc98bc. You can run:

git log 5fc98bc

to verify that. If that looks good, you should attach a new name to this commit to let you refer to it more easily—and to make sure it stays around longer than the default 30 days that you get to recover from mistakes.

Let's say this is correct (it's the only commit line I see in your entire git reflog output image and, as HEAD@{6}, it's immediately followed by a HEAD@{5} line written by git checkout -B), and you do not currently have a branch named saveme, so that this name is available. You can then run:

git branch saveme 5fc98bc

to attach the name saveme to it. Now git log saveme will show the commit(s), and git checkout saveme will get you on a branch that has those commit(s) in it.


The key to understanding all of this is to know that in Git, branch names are just ways Git has of getting into the commit graph. The names simply record the hash IDs (those incomprehensible strings like 5fc98bc). It's the IDs that actually matter; we humans just need names for them.

The commit graph represents every commit ever added to your repository, and what Git normally does is add new commits. This is true even when you use apparently-destructive commands like git reset. The commits themselves are not destroyed, they just become harder to find. But branch names also protect commits; eventually, if they're "too hard to find", Git will garbage-collect them and throw them out for real. Having a branch (or tag) name that identifies a commit protects that commit from this Grim Reaper Collector, and also protects all commits reachable from that commit.

This is all described quite well at http://think-like-a-git.net/ so you might want to spend some time reading those pages.

Upvotes: 2

NullDev
NullDev

Reputation: 7303

Note: as @MarcinOrlowski suggested, make a backup including the .git folder first.

Since its not only one file as you said in your comment, git checkout HEAD /your/file/path wont work. However, you can try

git checkout -

If that doesn't work try

git reset --hard HEAD

Upvotes: 1

Related Questions