Reverting Changes
Last updated on 2024-12-18 | Edit this page
Overview
Questions
- How can I recover old versions of files?
Objectives
- Restore old versions of files.
- Undo commits.
All right! So we can save changes to files and see what we’ve
changed. Now, how can we restore older versions of things? Let’s suppose
we change our mind about the last update to forecast.md
(the “ill-considered change”).
git status
now tells us that the file has been changed,
but those changes haven’t been staged:
OUTPUT
On branch forecast
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: forecast.md
no changes added to commit (use "git add" and/or "git commit -a")
We can put things back the way they were by using
git restore
:
OUTPUT
# Forecast
## Today
Cloudy with a chance of sun.
Mild temperatures around 16 °C.
## Tomorrow
Morning rainbows followed by light showers.
As you might guess from its name, git restore
restores
an old version of a file. By default, it recovers the version of the
file recorded in HEAD
, which is the last saved commit.
Restoring a file from further back
If we want to go back even further, we can use a commit identifier
instead, using -s
option:
OUTPUT
# Forecast
## Today
Cloudy with a chance of pizza.
OUTPUT
On branch forecast
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: forecast.md
no changes added to commit (use "git add" and/or "git commit -a")
Notice that the changes are not currently in the staging area, and
have not been committed. If we wished, we can put things back the way
they were at the last commit by using git restore
to
overwrite the working copy with the last committed version:
OUTPUT
# Forecast
## Today
Cloudy with a chance of sun.
Mild temperatures around 16 °C.
## Tomorrow
Morning rainbows followed by light showers.
It’s important to remember that we must use the commit number that
identifies the state of the repository before the change we’re
trying to undo. A common mistake is to use the number of the commit in
which we made the change we’re trying to discard. In the example below,
we want to retrieve the state from before the most recent commit
(HEAD~1
), which is commit f22b25e
. We use the
.
to mean all files:
The fact that files can be restored one by one tends to change the way people organize their work. If everything is in one large document, it’s hard (but not impossible) to undo changes to the introduction without also undoing changes made later to the conclusion. If the introduction and conclusion are stored in separate files, on the other hand, moving backward and forward in time becomes much easier.
Reverting Changes
Generally it is best to spot and revert mistakes before the commit stage. The table below summarises how to revert a change depending on where in the commit process you are:
To revert files you have … | git command |
---|---|
modified | $ git restore <files> |
staged | $ git restore --staged <files> |
committed | $ git revert <commit> |
We have already practised restoring modified files. Now let’s
practise restoring staged changes. Go ahead and make a similar change
like you did earlier to your forecast.md
:
OUTPUT
# Forecast
## Today
Cloudy with a chance of sun.
Mild temperatures around 16 °C.
## Tomorrow
Morning rainbows followed by light showers.
Another ill-considered change.
Add the changes:
Now git status
shows:
OUTPUT
On branch forecast
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: forecast.md
And we can use the hint to unstage our changes:
Our modifications to the forecast.md
file have been
unstaged and are now back in the working copy. We can restore these
modifications fully with:
Recovering Older Versions of a File
Jennifer has made changes to the Python script that she has been working on for weeks, and the modifications she made this morning “broke” the script and it no longer runs. She has spent ~ 1hr trying to fix it, with no luck…
Luckily, she has been keeping track of her project’s versions using
Git! Which commands below will let her recover the last committed
version of her Python script called data_cruncher.py
?
$ git restore
$ git restore data_cruncher.py
$ git restore -s HEAD~1 data_cruncher.py
$ git restore -s <unique ID of last commit> data_cruncher.py
Both 2 and 4
The answer is (5)-Both 2 and 4.
The restore
command restores files from the repository,
overwriting the files in your working directory. Answers 2 and 4 both
restore the latest version in the repository of the
file data_cruncher.py
. Answer 2 uses HEAD
to
indicate the latest, whereas answer 4 uses the unique ID of the
last commit, which is what HEAD
means.
Answer 3 gets the version of data_cruncher.py
from the
commit before HEAD
, which is NOT what we
wanted.
Answer 1 results in an error. You need to specify a file to restore.
If you want to restore all files you should use
git restore .
Reverting a Commit
Ahmed is collaborating with colleagues on a Python script. He
realizes his last commit to the project’s repository contained an error,
and wants to undo it. Ahmed wants to undo it correctly so everyone in
the project’s repository gets the correct change. The command
git revert [erroneous commit ID]
will create a new commit
that reverses the erroneous commit.
The command git revert
is different from
git restore -s [commit ID] .
. git restore
restores files within the local repository to a previous state, whereas
git revert
restores the files to a previous state
and adds then commits these changes to the local
repository. So git revert
here is the same as
git restore -s [commit ID]
followed by git commit -am Reverts: [commit]
.
git revert
undoes a whole commit whereas
git restore -s
can be used restore individual files.
Below are the right steps and explanations for Ahmed to use
git revert
, what is the missing command?
________ # Look at the git history of the project to find the commit ID
Copy the ID (the first few characters of the ID, e.g. 0b1d055).
git revert [commit ID]
Type in the new commit message.
Save and close.
The command git log
lists project history with commit
IDs.
The command git show HEAD
shows changes made at the
latest commit, and lists the commit ID; however, Ahmed should
double-check it is the correct commit, and no one else has committed
changes to the repository.
Key Points
-
git restore
recovers old versions of files. -
git reset
undoes staged changes. -
git revert
reverses a commit.