Maciej Ptak
written byMaciej Ptak
posted on August 25, 2022
DevOps Engineer/Consultant. Specialized in Salesforce and CICD tooling around it. Focused on removing the bottlenecks and streamlining the Salesforce delivery process since 2017.

How to recover deleted files in git

Git is hard: screwing up is easy, and figuring out how to fix your mistakes is f**king impossible.

How I restored not yet committed files in git

Hi! It happened to me a week ago so I thought it would be good to share this with you.
I was working on some shell script that developers would execute to automatically do some stuff on their local machine - casual DevOps day.
The script file was not yet staged in GIT so when I was doing git reset --hard origin/branch-name it stayed as it was. That command I was using in my script - I tested that multiple times and it was all right.

At some point when I was ready, I did a quick backup of a script, staged file, typed even the commit name - and I thought hmmmm - One more test and I will commit, push and done. So I did.

I did run the script after staging the file in git (git add command or plus button in IDE within source control view).

That was a mistake, the script ran, git reset --hard [...] erased my NOT yet committed script.
But at that point all I knew is that I ran ./path/to/my/fancyScript.sh and my file disappeared

Travolta looking for his git file

Time for little a panic attack 🙂

After some swearwords, I googled, how to restore not yet committed files and found one solution but it is a bit complex.

Problem origins

git reset --hard effect

If the file was committed in the past I could simply go back in history and restore it
git checkout {LAST_COMMIT_WITH_FILE} -- <path/to/file>

But in my case, it was not.
I found some commands, that might be useful, but they weren't helpful in my scenario:

  • fc -ln -5 - show the last 5 commands in the terminal (but not commands performed within a script)
  • history | tail - same as above but showing 10 lines

git commands

git reflog - to figure out what happened in git, it confirmed what I suspected, and there was a line:

  • {COMMIT_HASH} master, feature/test-one) HEAD@{3}: reset: moving to HEAD

So at that point, I knew what happened. Time to fix it now
git fsck --unreachable --no-reflog | grep blob > gitList.txt

  • --unreachable Print out objects that exist but that aren’t reachable from any of the reference nodes.
  • --no-reflogs Do not consider commits that are referenced only by an entry in a reflog to be reachable. This option is meant only to search for commits that used to be in a ref, but now aren’t, but are still in that corresponding reflog.
  • grep blob as we are interested only in this type. Blob is the object type used to store the contents of each file in a repository.

So we end up with a huge list of potential file contents

Now it is up to you, whether you want a nice, optimized one-liner or you are in a hurry.
I was in a hurry so I used multiline selection and created this little monster

ready git commands

git cat-file -p {BLOB_HASH} | grep 'bin/bash' && echo "{BLOB_HASH}"
you can grep any individual excerpt of file content. I was looking for a bash script so I used bin/bash

Then I just copied everything and pasted it into the terminal.
And I found some candidates:
git candidates

What was left was to check every single one with this command:
git cat-file -p {BLOB_HASH}
And guess what? The second from the top was the file content I lost.
Voilà la
Very easy, right? Right?!

If you know or found a better solution please let me know in the comment section below.

Lessons learned

I wouldn't need to do it if I would just do a commit or backup. But wait ... I wrote that there was a backup. And yes I did a backup but of a wrong file xD
So commit often, don't worry if that is the trash/in-progress, just do a merge --squash to reduce the number of not needed commits while merging
Do a proper backup, and check if the backup is okay and working. There is even a saying:

People fall into three categories:
(1) those who don't do backups
(2) those who do make backups
(3) those who think they are doing backups

Was it helpful? Check out our other articles here.


References

Buy Me A Coffee