Get the hash of the “good” version you want to recover
You first need to identify where things went wrong. Then get the commit identifier (also called the hash) for the version immediately prior to that. (Also make sure you’re pulling from the appropriate branch; for simplicity’s sake, this example assumes all changes are being committed to the master branch.)
# git log commit 07c5f535743e3f70fcdf09c0d032580820ca38c9 Author: Toby Base <firstname.lastname@example.org> Date: Tue May 19 14:33:17 2020 -0500 Created content/post/my-newest-article.md (Oh no! Accidentally deleted some files after the last commit!) commit 85add47b28670abaf99b17e010edeafb2fbb3189 Author: Toby Base <email@example.com> Date: Fri Feb 7 21:04:39 2020 +0000 Updated content/post/oracle-cloud-day-dallas.md commit c3a520e136dc90e7982bc50d56a33aa3c3885f85 Author: Toby Base <firstname.lastname@example.org> Date: Fri Feb 7 21:02:29 2020 +0000 Created static/uploads/BC9419D3-B290-4CF3-845C-5C008A19419C.jpeg
In my case, I know I deleted files in the commit on May 19. So I want to restore those files from the version right before that, the one with hash
Flash back to the state of the repository at the desired commit
Do this only if you don’t care about eliminating commit history or losing changes since the specified commit.
# git reset --hard 85add47b28670abaf99b17e010edeafb2fbb3189
Other options for
git reset include
--mixed, which retain the changed files in your working directory, but treat the states of those files differently. A more thorough explanation of how
git reset works can be found here.
Recover files while retaining the commit history
# git checkout -b new_branch 85add47b28670abaf99b17e010edeafb2fbb3189
The checkout command will revert any unchanged files and restore any deleted files as of the specified commit. New and changed files since that time are retained. We fork a new branch in order to avoid the “detached HEAD” state, discussed in the above linked article, that could lead to problems on future commits.
If you were working on the master branch and want to continue committing changes on that branch, simply commit your changes on the new branch, switch back to the master, and merge in your changes.
# git add -A # git commit -m "Restoring files from previous commit" # git checkout master # git merge new_branch
checkout master switches us back to the master branch, and then we use
merge new_branch to restore the lost files to the master.
Another option just to recover the files
The simplest way to get your files back without dealing with the branching and merging is to checkout a prior version in a temporary directory, then copy the missing files from there back to your working directory. Then just add and commit those files back to source control.
# cd /tmp # git clone https://github.com/toby-marks/tobybase.git # cd tobybase # git checkout 85add47b28670abaf99b17e010edeafb2fbb3189 # cp content/posts/*.md /path/to/tobybase/working/directory/content/posts/ # cd /path/to/tobybase/working/directory # git add -A # git commit -m "Restoring files lost after 85add47b28670abaf99b17e010edeafb2fbb3189"