Skip to content

Restore Files (git restore)


What Will We Learn?

Restroing files from different Git states. Don’t miss the following Real World Analogies:

What git restore Can Restore?

git restore can restore files in your working directory and unstage changes. It can also pull up specific version of files from previous commits.

Knowing git restore’s default can be helpful as it avoids whole lot of confusion moving forward. First, you need to know three stages of Git.

    flowchart LR
    WorkDir[Working Directory]
    Index["Staging Area (Index)"]
    Repo[Git Repository]

    WorkDir --> Index
    Index --> Repo
  

At the very basic git restore <path>, restores files in the <path> from the very next area. Files will be restored as per following priority rules:

  • Files will be restored from the index if they are staged
  • Else they will be restored from the latest commit (if any)
  • If nothing committed yet, restoring is no-op

Restoring Files in Working Dir

By default, git restore restores files to the working directory.

Real World Analogy

Suppose the content of file.txt in your working directory is:

    flowchart LR
    file[file.txt]
    content["good luck"]
    file -- content --> content
  

You staged it with git add file.txt. Now again, you modified your file.txt and the content now is:

    flowchart LR
    file[file.txt]
    content["hello world!"]
    file -- content --> content
  

You thought that good luck version was the better version of file.txt. You have now two option:

  • Manually edit file.txt to good luck version
  • Use git restore file.txt

Yes you can manually edit the file but the problem is the size of file and your memory.

Do you even remember previous best version in case of mistake?

Are you seriously going to edit 1000 lines of code manually just to match previous best version?

Usage

So, remember the usage:

git restore file.txt

You also can restore multiple files:

git restore file.txt app.py src/

Warning

Restoring overrides the contents in the working directory which is a destructive operation. Be cautious while using.

Restoring Staged Files

Unstaging files is doing using --staged option.

Real World Analogy

See see different version of file in different stages.

# file in working dir
$cat file
greet

# file in the index (staged)
$git show :file
hi

# latest commit of file
$git show HEAD:file
hello

Both working dir and index are modified which can also be verified by git status:

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   file

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   file

The meaning of staging is that “this version of file will be included in the next commit”. But sometimes, even after adding you are not sure that this will be the next best version of file and you want to unstage it. The --staged option will help you.

git restore --staged file

Now the content of file is:

$git show :file
hello

And it is not staged for commit (git status):

On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   file

no changes added to commit (use "git add" and/or "git commit -a")

Tip

You will often use --staged option when your current modified version of file which is already staged is not ready for commit.

Please focus in the phrase which is already staged.

Usage

Using it is simple. Just add --staged option and provide to restore.

git restore --staged src/ main.c

Tip

If you want both to unstage and restore in working directory, you can pass --worktree option along with --staged

Restoring From Specific Commits

You can pass specifc commit hash or identifier to --source option to restore file from that specific commit.

Real World Analogy

See the different version of file in different commits.

# file in working dir
$cat file
namaste

# file in current commit
$git show HEAD:file
namaste

# file in previous commit
$git show HEAD~1:file
greet

# file in 2 commits prior to current comment
$git show HEAD~2:file
hello

You find hello version of greeting works best for your use case but your current version is namaste. To restore file that will match hello version, you use:

git restore --source HEAD~2 file

Now the current version is:

$cat file
hello

One thing to see is git status:

On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   file

no changes added to commit (use "git add" and/or "git commit -a")

After you restore from particular commit, the file is modified which does not match to the latest commit. This means, you IDE will show Modified marker (M) and you need to add and commit it in order to make it permanent.

Usage

Just use --source option to provide source commit to restore from.

git restore --source <commit> <path>
Last updated on