BackHub Blog

Recovering Deleted Files in GitHub

Every developer has deleted the wrong file from their project at least once. It can either be a hastily executed `rm -rf` command, or an absent-minded select and delete, or maybe the result of an erroneous script. Whatever the reason, deleting an important file can be troublesome if not fixed immediately. When working with a team, accidentally deleting a file and then pushing it upstream can be catastrophic for other team members who pull the changes. Depending on the file, either they’ll get an error straight away, or in the worst case, the error will pop up somewhere down the line—maybe in some not-so-obvious place—at which point, it might be difficult to figure out the exact cause.

So, now that you have accidentally deleted a file, or files, how do you recover them? Since Git is a version control system, it has features to roll back a single file to a previous version, including deleted files. 

In this tutorial, we’ll look at three ways to recover a deleted file: using the Git command line, using GitHub’s web and app UI, and using a full-scale backup solution with BackHub.

You can follow along with this tutorial by cloning the demo repository.

Recovering Deleted Files with the Command Line

Recovering a deleted file using the Git command line involves the `git restore` or `git checkout`command. Whenever you modify files in Git—including creating new files, editing, or deleting existing files—the changes start as unstaged. Then you stage the changes with the `git add` command, and finally, you commit the changes using the `git commit` command. Git provides ways to recover a deleted file at any point in this life cycle of changes.

If you have not staged the deletion yet, simply run `git restore <filename>` and the file will be restored from the index. 

A screenshot showing the git restore command.

If you have staged the changes, however, running `git restore` will throw an error, since the file does not exist in the index anymore.

A screenshot of the git restore command throwing a error.

In this case, you need to run `git restore --staged --worktree <filename>`. The `--staged` argument tells `git` to restore the file in the index from HEAD, and the `--worktree` argument tells Git to restore the working tree as well.

A screenshot showing the git restore command with a properly staged worktree.

If you have deleted the file and already committed the changes, you need to use the `git checkout` command to restore the file. First, you need to find out the checksum of the commit that deleted the file, and then check out the file from the previous commit.

In the demo repo, `file1.txt` has already been deleted and committed. Let’s recover that file. To figure out which commit deleted `file1.txt`, you need to use the `git rev-list` command:

```

git rev-list HEAD -n 1 -- file1.txt

```

Screenshot showing git rev-list

This command tells `git` to list all commits, which can be reached from the HEAD, that changed the file `file1.txt`. The `-n 1` option tells `git` to limit the result to only one commit. The output is the checksum of the commit that deleted the file. You can check that this is the offending commit by using the `git show` command with the checksum -

Screenshot showing git show

The commit before this one is the last commit where this file was present. You can restore the file from that particular commit by running the following command. The `^` at the end of the commit hash tells Git to fetch the commit before this one:

```

git checkout 3d5210ddd8632d539ed3f5e362dc047ed508a510^ file1.txt

```

Screenshot showing git checkout

Pros and Cons of Using the Command Line

This method is the quickest to perform since you only need access to the command line. However, it requires you to run different commands depending on your situation. Also, it might not be the easiest to master, and some developers may prefer a more visual approach.

Using the GitHub Desktop App

If you are more comfortable with a graphical interface, you can use the GitHub Desktop, which is available for macOS and Windows. Similar to the previous case, there are two scenarios: one where you have not committed the deletion, and one where you have.

Any changes you make in your repository will show up in the staging area in the left sidebar of the app. There you can discard the changes, which works similar to the `git restore` command. If you have not yet committed the deletion, you can use this feature to quickly recover the deleted file.

Go ahead and delete `file5.txt` from the repository and come back to GitHub Desktop. You should see the deletion in the staging area.

Screenshot showing the unstaged changes

You can right-click on the change and click on Discard changes.

Screenshot showing discard changes menu

You will be asked for confirmation. Once confirmed, the change will be discarded and the deleted file will be back in its place.

Screenshot showing the confirmation dialog

If you have already committed the change, you need to know the commit hash of the offending commit. There is no way to do that from the GitHub desktop app, so you need to use the command line and run the `git rev-list` command we discussed earlier.

Just like before, let’s restore the already deleted `file1.txt`. First, you need to know the hash of the commit that deleted the file:

```

$ git rev-list HEAD -n 1 -- file1.txt

3d5210ddd8632d539ed3f5e362dc047ed508a510

```

In the app, the commits are listed with their names, not hashes. In order to know the name of the commit, you need to run `git show` command with the commit hash: 

```

git show 3d5210ddd8632d539ed3f5e362dc047ed508a510

```

Screenshot showing the name of the commit

The name of the commit is “Add file4.” Next, locate this commit in the History tab in the app.

Screenshot locating the commit in the history tab

Right-click on the commit and select Revert changes in commit.

Screenshot showing the revert changes menu

This will revert the offending commit and create a new commit.

Screenshot showing the new commit

Pros and Cons of Using GitHub Desktop App

This method is comparatively easier than using the command line and a better choice if you’re comfortable with graphical interfaces. However, it has the following disadvantages:

  • The desktop app is only available for Windows and macOS. If you’re using Linux then you won’t be able to use this method.
  • If you have already committed the deletion, this method becomes cumbersome since you need to use the command line to find the commit name and then search through the history in the app to locate the commit.
  • It is not possible to check out only the required file from the commit using this method. You need to revert the entire commit, which means any other changes made by the commit will be reverted as well.

Using the GitHub Web UI

If you have committed the deletion and pushed it to GitHub, it is possible to recover a deleted file using the GitHub Web UI. GitHub lets you browse the commit history and explore the project at any point in history, which then allows you to view and download any file.

Let’s recover the already deleted `file1.txt` in the repository. Similar to the previous approach, you need to know which commit deleted the file, using the `git rev-list` command explained before. In our case, the commit hash is `3d5210ddd8632d539ed3f5e362dc047ed508a510`.

Open a browser and visit the URL - `https://github.com/<username>/<repo-name>/commits/3d5210ddd8632d539ed3f5e362dc047ed508a510^`. Make sure to replace `<username>` and `<repo-name>` to point to your repository. This will open up the commit before the offending commit.

Screenshot showing the commit page

Click on Browse files and you will be presented with the project structure of that particular commit.

Screenshot showing the file structure

Find the file you want to restore. In this case `file1.txt`. Open it by clicking on it.

Screenshot showing the contents of file1.txt

Click on the Raw button and you will be presented with a raw text version of the file. You can right-click on the page and select Save As to download the file and save it to your project. Now you can add it back to your local repo and commit -

```shell

git add file1.txt

git commit -m "Reintroduce file1.txt"

```

Pros and Cons of Using GitHub Web UI

Similar to using the app, this method is easier to use than the CLI method because of its graphical interface. You can also visually browse the repository at any point of your commit history without having to clone or checkout the commit.

The biggest disadvantage of this approach, however, is that there is no way of selecting and downloading more than one file. So if you have accidentally deleted more than one file, you have to download them one by one—a time-consuming task. Additionally, this method somewhat relies on the command line since you need the command line to figure out the commit hash.

Using a Full Backup

Recovering a deleted file with Git is a comparatively complex process. Not only do you have to dabble with the command line to try and figure out the commit hashes, but you also have to make sure that the commit you’re restoring the file from is indeed the correct one. If you have accidentally deleted more than one file, restoring them from different commits can introduce inconsistency into your project. Using a full backup solution like BackHub can save you some trouble by backing up the entire repository, thus ensuring a consistent state. 

BackHub offers powerful features like nightly snapshots, Amazon S3 sync, backing up repository metadata (issues, pull requests, wiki, etc.), and the ability to clone any snapshot directly from the BackHub server. Using their full backup solution will ensure you do not have to fiddle with Git when you accidentally delete one or more files. Instead, you can just restore from a nightly backup. Even better, you can restore a deleted repository in just a few clicks if you happen to accidentally delete one.

Let’s learn the process of installing BackHub and restoring files from the backup.

Installing BackHub

BackHub plans start from $12 per month. You can sign up for a free trial from the installation page. After signing up, you’ll be directed to an install screen that sets up permissions with your GitHub account. Here you can select which repositories you want to back up using BackHub. You can either choose All repositories to back up all of your projects or individually select as many as you like. If you choose All repositories, any new repository you create on GitHub will automatically be backed up.

From there, you need to sign in to GitHub and authorize BackHub to finish the installation. Once you return to your BackHub dashboard, you should see a list of backed-up repositories.

Screenshot of the BackHub dashboard

From this point onward, BackHub will keep nightly backups of the repositories. The snapshots are stored for thirty days, but up to 1 year (365 days) of storage is available for enterprise plans. You can also connect an S3 bucket in the settings if you’d like to preserve the snapshots indefinitely.

Restoring a Full Backup

Let’s go over the steps of restoring a deleted file with BackHub.

First, let’s delete a file and push.

```

rm file5.txt

git commit -am "Delete file5.txt"

git push origin main

```

In the BackHub dashboard, select the repository you’d like to restore.

Screenshot of the selected repo

On the left-hand side, you can see the time of the latest backup and the number of snapshots BackHub has created. If this is a recently added repository, you will have only one snapshot of the current version. If the repository was added some time ago, you will have daily snapshots and you can choose the snapshot of any day to restore.

Screenshot of the choose snapshot dialog

Once the snapshot is chosen, click on the Download Files button. The download will contain a ZIP with all the files from the head of the main branch. From there, you can easily copy over the deleted file `file5.txt` to your local repository and welcome it back with a commit:

```

git add file5.txt

git commit -m "Reintroduce file5.txt"

```

Conclusion

Accidentally deleting important files is every developer’s nightmare. With Git not having an intuitive undo command, it can be difficult to efficiently restore a deleted file.

With a full backup solution ready, however, you can rest assured you’re able to combat any issues that might occur because of deleted files. You’ll also be able to restore deleted files without issue. Having a full backup solution can prove to be useful in the long run, especially in critical business software or team-based environments. Check out BackHub for one of the best complete backup and restore solutions. See it in action yourself: start your free trial of BackHub.