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.txtto 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.txtYou 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
helloBoth 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: fileThe 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 fileNow the content of file is:
$git show :file
helloAnd 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
git restore --staged src/ main.cTip
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
helloYou 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 fileNow the current version is:
$cat file
helloOne 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>