Git: Restoring a Lost File

Russell Bateman
22 March 2012
last update:

If you lose a file...

For example, a colleague had some trouble merging and fixing conflicts one day and asked me about a JUnit test, AccountManagerTest.java. I thought it was just one of several empty JUnit stubs that I had tried to remove several times and, without thinking much about it since I was hard at it on something else I was doing, told him just to toss it.

Well, it wasn't empty. In fact, it was a lot of code I had finally written to fill in the stub.

So, big oops, how to get that back?

Retrieving a lost file

russ ~/acme/rest-server/test/com/acme/user/manager $ git rev-list -n 1 HEAD -- AccountManagerTest.java 55d65f7d06359c80e45de8d8ff7f05f4a8fa8516 russ ~/acme/rest-server/test/com/acme/user/manager $ git checkout 55d65f7d06359c80e45de8d8ff7f05f4a8fa8516^ -- AccountManagerTest.java russ ~/acme/rest-server/test/com/acme/user/manager $ git add AccountManagerTest.java russ ~/acme/rest-server/test/com/acme/user/manager $ git commit russ ~/acme/rest-server/test/com/acme/user/manager $

...and, presto, there it was! The first command discovers the associated hash of the most recent commit for that file. The second backs things up one commit: it's the caret (^) that backs up by 1.

I'm told that the two commands can be combined into (more or less) one—so you don't have to copy and paste the hash. I say more or less because I'm going to put the filename into a shell variable so I don't have to type it twice (ok, cheap thrills, I know).

$ file=AccountManagerTest.java $ git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"