Using checkout

Restore a target. Path is required, otherwise nothing will change.

$ git checkout PATH

Restore directory using a single dot. This is recursive - current directory and below. Do this from the repo root if needed.

$ git checkout .

Restore to a commit reference. Such as a tag number, a commit hash, or a branch name (e.g. master, my-feature). The path could be . or a directory or filename.

$ git checkout COMMIT_REF PATH

Use reset or checkout

Restore a file to an earlier state. This includes bringing back a file that was deleted.

If you are on a feature branch and the file is still on master, you can reset to the master (note targeting just the file path). Either of these will work:

$ git reset --hard COMMIT_REF PATH
$ git checkout COMMIT_REF PATH

e.g.

$ git reset --hard master foo.txt
$ git checkout master foo.txt

When using reset, if you leave out --hard then you need to remove the unstaged portion of the file liek this:

$ git checkout .

Then commit the file that is staged.

Either way, if you bring back a file, you get to keep the history of the file, which you can see:

$ git log PATH

e.g.

$ git log foo.txt

The approach works great on a directory too, to restore multiple deleted or changed files to what is on master. Use of these:

$ git reset --hard .
$ git checkout .

Restore file deleted file

If you are are a feature branch, you can use the reset or checkout approaches above against master to bring a file back. But, if you are already on master and pushed, you can’t use target master or origin/master to bring a file back.

So now you have to use the last-known commit - you have to find the commit on master before that file was deleted.

From StackOverflow, find the last commit that affected the given path and restore the given path to the commit just before it. Hence use carat - ^.

$ git checkout $(git rev-list -n 1 HEAD -- PATH)^ -- PATH

As the file isn’t in the HEAD commit, this commit must have deleted it.

Note that HEAD is literal and PATH will be your file or directory.