Quick cheat sheet to perform git restore
Git restore is frequently confused with other commands such as checkout, revert, reset, and switch. The reason being it came into existence when some of the commands were already solving its primary roles.
Also, some of its features could be undergoing the experimental stage, making it hectic to realize the best way to apply it. The four stable forms of the git restore command are
git restore --staged <file>
to undo changes in the staging area,
git restore --staged --worktree <file>
to restore changes in both the staging area and the working tree. Use
git restore --source=<path> <file>
to restore changes along a branch, tag, or on a commit hash, and
git restore --patch
restore modified changes interactively.
It would help to take a realistic look at the four git restore flags and their alternatives. But, before that, you should understand the terms often confused with git restore.
The role of git restore in a standard git workflow
Although git restore can discard changes in the working tree, it mainly affects the index. The index also called the staging area, is the second level of the main git workflow. The first stage is the working tree, where you introduce new files or modify the ones already in the index or history.
After creating the files, you store them in the git database after keeping a copy of the changes in the index. On committing the changes, they become part of the history and are identifiable with a commit hash.
Depending on the number of developers collaborating on a project, you may open and merge several branches.
Transitioning from one development line to another may require undoing, discarding, or reinstating deleted changes. That calls for using various commands such as git restore.
Simple explanations of terms often confused with git restore
Git checkout, switch, reset, and revert often get confused with git restore. Here's what you should know about the commands.
Git checkout used to be one of the most overworked commands before launching git version 2.23. It undoes changes in a file or a commit and switch between branches. Now, git recommends using the git restore command for most git discard change processes.
You can also use the git switch command to navigate branches by creating and checking out a branch using a one-line command.
The reset command returns the HEAD to a specified state. More often, git reset updates a branch and often overlaps with git restore. On the other hand, git restore does not update a branch and mainly affects files in the working tree.
The revert command is a safer way to reset changes. The main difference between git reset and the git revert is that the revert command rewrites the commit history instead of discarding the history. While git revert rewrites the commit history, git restore does not generate new commits.
Let us set up a lab and see the differences practically.
Set up a lab to explore the git restore command
I am creating a repository on GitHub called git_restore
,
Copy its URL and clone it on the command line.
Let us create a file.
cd git_restore touch file
Stage
git stage file
and commit it.
git commit -m "Track file"
Now that we have a repository to play with, let us see practical examples of the git restore command.
Relatable examples to differentiate restore, checkout, reset, revert, and switch commands
Although git checkout can still help undo changes in a file, commit or tag, its primary usage after introducing git version 2.23 is switching between branches. Here is an example:
I am creating and moving into new_branch
.
git branch new_branch git checkout new_branch
or create and checkout a branch using the -b
flag.
git checkout -b new_branch
The hard reset command helps to discard changes. For example, let us remove the last commit.
Check the target commit hash.
git log --oneline
And hard reset it.
git reset --hard 463fe07
Rechecking the file, we realize it got deleted from the working directory. Neither can we trace its commit from history.
We can restore the file using reflog
and a hard reset on the discarded commit.
git reflog git reset --hard 9f2c58a
The file is back to the working tree. A soft reset changes the commit HEAD by removing the changes from the history to the index. Lastly, a mixed reset on the HEAD unstages the file. As you will see in example-1, it works in a similar manner as git restore --staged <file>
.
Let us use it to unstage file2
as follows:
Create file2
.
touch file2 git stage file2
Unstage it.
git reset HEAD file2
Since the (hard) reset command is destructive, you should avoid it when undoing changes on files you have pushed. Instead, use git revert.
Let us restage file2
, commit and push it.
git stage file2 git commit -m "Track file2" git push
We can then revert the changes as follows:
git log --oneline git revert 463fe07
Git opens our text editor, prompting us for a new commit message. We can accept the default commit message and close the text editor. This time around, git created a new commit.
Lastly, we can use the git switch to check out branch_b
.
git switch -c branch_b
Let us now use three examples to explore the git restore command practically.
Git restore using various flags
Example-1: Using the --staged
flag
Modify file2.
echo modified >> file2
Check status.
git status
The changes are untracked and marked in red. Let us stage the changes and recheck the status.
git add file2 git status
The files are green, meaning they are staged. As git hints in the below screenshot, we can unstage the changes by specifying file2
in the git restore command.
git restore --staged file2
And recheck the status.
git status
Our files are back in the working directory.
We can also restore changes in the index and the working tree.
Stage file2
.
git add file2
Modify it.
echo changed >> file2
Restore the index and working tree.
git restore --staged --worktree file2
Both changes got wiped out.
Example-2: Using the --source
flag
Modify file2
and check out the main branch.
echo modified >> file2 git checkout main
Restore the file by specifying the branch name and file.
git restore --source=branch_b file2
Return to branch_b
and check the status.
git checkout branch_b git status
Our changes disappeared!
Example-3: Using the --patch
flag
We can interactively restore the modified changes using the --patch
flag.
Check out the main branch.
git checkout main
Modify the file and check the status.
echo changed >> file git status
Running git restore using the --patch
flag
git restore --patch
asks us to pick the restore option. Let us go with y for yes. Our changes got restored.
Conclusion
Git restore's role changes according to the flag supplied. For example, the --staged
flag works as a mixed reset on the HEAD, The --staged --worktree
and --patch
flags discard files from the working directory, just like git reset hard on a commit.
Git checkout can undo changes on a file, tag, or commit. After introducing the restore command in git 2.23, the checkout command, like the git switch, mainly helps in navigating branches. Finally, git revert is a safer path to undo changes on commits already pushed.