Recovering from Git-pocalypse

So, something went wrong and your work has disappeared, you've gone through at least a couple of the stages of grief, and are now Googling frantically to find the incantation you can cast to recover what you've lost before finally giving up and accepting that what is done is done.

This isn't what version control is about.

But it's gone, isn't it?

I am still surprised at how many VCS users just don't get it. VCS is by design meant to stop this from happening, the token line I use to describe version control being:

Don't lose stuff ever again, seriously.

Even I used to have the fear, but then again I used to be a Subversion user and the threat was very much real. With Git, it is nigh on impossible to lose a commit, you literally have to filter branches and go to a tremendous effort to do it, you're probably not going to do it accidentally unless you're blindly running crazy commands or your hardware melts.

So where's my stuff?

To understand this, first you need to know a little about how Git works, and when I say a little, I really do mean that.

As you almost certainly know, your changes are stored in commits, these are fundamentally records of what your files look like, or rather, their journey from being created up until this point.

You might also have a loose idea of what branches are, they're where commits live, right? Well not exactly, a branch simply represents the head of a line of work, the head being the most recent commit in that line of work. You can also think of it representing the ancestry of that commit, whilst perhaps not factually accurate, it may help your understanding of how to use them.

This means that when you commit stuff, or use reset to go back a few commits, nothing is being deleted, you're simply traversing back and forth along a timeline, commits are independent, that's why you can merge branches and create tags etc. etc. they're all just collections of references.

So what does this mean when it comes to disaster recovery?

Well, most of the time, if you think you've lost your work, you've probably just orphaned the commits- that's to say, your branch's head now references an older commit and it, nor any of your other branches reference a timeline that contains your recent work. Don't panic, commits persist indefinitely unless you manually purge them, and again, that requires effort.

How do I get it back?

Usually it's as simple as merging the commits back in, but to do that you'd need to know their hashes, or at the very least the hash of the most recent commit, merging it of which would pull in any missing ancestry also.

If you don't know the hashes, i.e. they're not in your bash history, or you're using a GUI, or whatever, then the reflog should be your first point of call.

git reflog

The output returned from this command may be a little daunting to those unfamiliar with CLI, but look at it this way, it is effectively a log of everything that has happened, not in terms of commits, but in terms of changes to the branch's head, which in laments terms, is equivalent to a log of all the stuff that has happened.

Usually the reflog will lead you to some kind of theory or even a conclusion regarding what has happened, it'll probably say something or other about your branch being reset to a particular point- you can usually take the hash of the commit before then and simply merge it in, the output that follows should reveal your changes being re-applied, and then you're probably done- you can punch it.

If you're still having problems, do what I do, don't bother remembering the command(s), hopefully you don't need these ones at hand that often (seek help if you do), simply Google "git locate orphaned commits", you'll be able to remember that easier anyway- there are various Stack Overflow questions there that have commands you can try, and maybe even a better explanation of what's going on than my attempt here.

I hope this helps! The main thing I want you to take away is that your code is more than likely to be safe, and retrievable, you just have to have the know how- and hopefully with this article you're a little closer if not fully confident with recovering your work.

If anyone else has any other examples of or tips for recovering from git-pocalypse, please do share them in the comments.