Un-delete file from a commit

Hi all, We’re finding that new non-dev teammates are running into a persistent snafu using GitHub Desktop – It’s just too easy to delete files unintentionally in a commit.

Can anyone help or better yet point me to documentation (if it exists, it’s not easy to find) showing how to navigate this example --? :

A user has made a commit that modifies 10 files and accidentally deletes 3 files. (The deletes were unintentional.) This commit has become part of a branch/PR where significant collaborative work has taken place since, so we don’t want them to start from scratch.
All we want to do is *not* delete the 3 files, and reverting the original commit is not the answer.

How do I get a non-dev user to fix the original commit (un-delete), in GitHub Desktop? 
Ideally by doing something other than manually re-adding back the 3 files in a new commit – because that defeats the point of version control in our view.

Finally, any upvotes for a  GitHub Desktop safe-mod feature for beginners like “Are you sure you want to delete these files from the repo?”

thanks! 

If you know the hash of the commit where the files were deleted and the paths to the files within the repository, you can do this in a couple git commands from the command line. Unfortunately, I don’t know of a way to do this via GitHub Desktop.

If you take a look at the test repository I created for this, you’ll see a few branches. mistaken-commit points to the commit where the files were deleted. broken-state points to where the file deletions were discovered. fixed-state points to the commit where the file deletions were restored using the technique below.

The general syntax of the command to restore the files is:

git checkout [hash-or-ref]^1 [file-list]

What this does is “checks out” the files in file-list in the state they were in one commit prior to hash-or-ref. The ^1 (which can be abbreviated to ^) means “one commit before” whatever it follows. So master^1 or master^ means the commit just before master.

So if you’re on the branch where the successive collaboration has taken place at the location where broken-state is, you could issue the command:

git checkout mistaken-commit^1 foo/bar.md foo/baz.md foo/foo.md

This would restore the deleted files as they existed one commit before mistaken-commit to your current working tree and index. Then you would commit that change using git commit as normal. This creates a new commit at your current location in the branch that restores only the deleted files you listed.

Additionally, if you don’t know the hash of the commit where the files were deleted, you can use the command:

git log --diff-filter=D --summary

And it will walk up the list of commits looking for commits that contain deletions. For example, here’s the output of me running that command in my test repo:

commit 0fa7e50ebfd599a1408469940c7313a4a953bea6 (mistaken-commit)
Author: Lee Dohm <1038121+lee-dohm@users.noreply.github.com>
Date: Thu Jan 9 11:56:03 2020 -0800

    Mistaken commit

 delete mode 100644 foo/bar.md
 delete mode 100644 foo/baz.md
 delete mode 100644 foo/foo.md

The big long hexadecimal number after commit on the first line there is the hash. You can use it in the place of the branch name in the undelete command I showed above.

I hope that helps! Let us know if you have any more questions.

1 Like