Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions book/02-git-basics/sections/undoing.asc
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,90 @@ If you would like to keep the changes you've made to that file but still need to
Remember, anything that is _committed_ in Git can almost always be recovered.
Even commits that were on branches that were deleted or commits that were overwritten with an `--amend` commit can be recovered (see <<ch10-git-internals#_data_recovery>> for data recovery).
However, anything you lose that was never committed is likely never to be seen again.

[[undoing_git_restore]]
==== Undoing things with git restore

Git version 2.25.0 introduced a new command: `git restore`.
It's basically a alternative to `git reset` which we just covered.
From Git version 2.25.0 onwards, Git will use `git restore` instead of `git reset` for many undo operations.

Let's retrace our steps, and undo things with `git restore` instead of `git reset`.

===== Unstaging a Staged File with git restore

The next two sections demonstrate how to work with your staging area and working directory changes with `git restore`.
The nice part is that the command you use to determine the state of those two areas also reminds you how to undo changes to them.
For example, let's say you've changed two files and want to commit them as two separate changes, but you accidentally type `git add *` and stage them both.
How can you unstage one of the two?
The `git status` command reminds you:

[source,console]
----
$ git add *
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: CONTRIBUTING.md
renamed: README.md -> README

----

Right below the ``Changes to be committed'' text, it says use `git restore --staged <file>...` to unstage.
So, let's use that advice to unstage the `CONTRIBUTING.md` file:

[source,console]
----
$ git restore --staged CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: README.md -> README

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: CONTRIBUTING.md

----

The `CONTRIBUTING.md` file is modified but once again unstaged.

===== Unmodifying a Modified File with git restore

What if you realize that you don't want to keep your changes to the `CONTRIBUTING.md` file?
How can you easily unmodify it -- revert it back to what it looked like when you last committed (or initially cloned, or however you got it into your working directory)?
Luckily, `git status` tells you how to do that, too.
In the last example output, the unstaged area looks like this:

[source,console]
----
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: CONTRIBUTING.md

----

It tells you pretty explicitly how to discard the changes you've made.
Let's do what it says:

[source,console]
----
$ git restore CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: README.md -> README

----

[IMPORTANT]
=====
It's important to understand that `git restore --staged <file>` is a dangerous command.
Any local changes you made to that file are gone -- Git just replaced that file with the most recently-committed version.
Don't ever use this command unless you absolutely know that you don't want those unsaved local changes.
=====