29 29. Viewing History and Undoing Changes
Commits are only useful if you can look back at them and use them to undo mistakes. This page shows you how to read the history, see exactly what changed, and undo changes safely. It continues with the practice project from Your First Repository, which has two commits so far.
29.1 Viewing history: git log
git logOutput:
commit b90f840eb88afb1f49b39e019d369b3c837a311a (HEAD -> main)
Author: Maria Lopez <maria@example.com>
Date: Tue Oct 6 10:22:00 2026 -0400
Describe planned pages in README
commit ffd1f1f288e0fd9bcff8162ce43136cb6eb4318b
Author: Maria Lopez <maria@example.com>
Date: Tue Oct 6 10:15:00 2026 -0400
Add starter files for portfolio site
Each entry shows the full commit ID (hash), the author, the date, and the message. The newest commit is at the top. (HEAD -> main) marks where you are now: on the main branch, at its latest commit.
When the history is longer than your window, Git shows it in a scrollable viewer: use the arrow keys or Space to scroll, and press q to quit.
Some useful variations:
| Command | Shows |
|---|---|
git log --oneline |
one line per commit: short ID and message |
git log -3 |
only the 3 newest commits |
git log --stat |
which files each commit changed, and how many lines |
29.2 Seeing what changed: git diff
Open src/index.html in your text editor and replace the line <p>Under construction!</p> with these two lines, then save:
<p>Hi, I'm Maria. I study business and build websites.</p>
<p>Contact: maria@example.com</p>Before you commit, ask Git what you changed:
git diffOutput:
diff --git a/src/index.html b/src/index.html
index ad87688..390be80 100644
--- a/src/index.html
+++ b/src/index.html
@@ -6,6 +6,7 @@
</head>
<body>
<h1>Welcome to My Portfolio</h1>
- <p>Under construction!</p>
+ <p>Hi, I'm Maria. I study business and build websites.</p>
+ <p>Contact: maria@example.com</p>
</body>
</html>
29.2.1 How to read a diff
--- a/src/index.htmlis the old version,+++ b/src/index.htmlthe new one.- Lines starting with
-were removed (red in the terminal); lines starting with+were added (green). Lines starting with a space are unchanged context, shown to help you find your place. - A changed line appears as a removed line followed by an added line.
@@ -6,6 +6,7 @@says where you are in the file: the snippet starts at line 6 and is 6 lines long in the old version, and starts at line 6 and is 7 lines long in the new version. Sometimes Git adds a nearby line of the file after the second@@as a landmark.- You can ignore the
index ...line; it contains Git’s internal IDs.
29.2.2 git diff vs. git diff --staged
Stage the file and run git diff again:
git add src/index.html
git diffThis time there is no output. That’s because git diff compares your working directory with the staging area, and they are now the same. To see what you are about to commit, compare the staging area with the last commit:
git diff --stagedIt prints the same diff as before. A diagram:
working directory <-- git diff --> staging area <-- git diff --staged --> last commit
Now commit:
git commit -m "Add intro and contact email to home page"Output:
[main 4293e1d] Add intro and contact email to home page
1 file changed, 2 insertions(+), 1 deletion(-)
The history now has three commits:
git log --onelineOutput:
4293e1d (HEAD -> main) Add intro and contact email to home page
b90f840 Describe planned pages in README
ffd1f1f Add starter files for portfolio site
29.3 Looking at one commit: git show
git show followed by a commit ID prints that commit’s details and its diff. You only need the first few characters of the ID:
git show b90f840Output:
commit b90f840eb88afb1f49b39e019d369b3c837a311a
Author: Maria Lopez <maria@example.com>
Date: Tue Oct 6 10:22:00 2026 -0400
Describe planned pages in README
diff --git a/README.md b/README.md
index 512dd88..9af11fc 100644
--- a/README.md
+++ b/README.md
@@ -5,3 +5,4 @@ This is a simple website project to learn Git!
## What it does
A personal portfolio website.
+It will have a home page and a contact page.
git show without an ID shows the latest commit. (In Git, HEAD is a name for “the commit you are on now”, so git show HEAD does the same.)
29.4 Undoing changes
Which command you need depends on where the mistake is:
| Situation | Command | Can you lose work? |
|---|---|---|
| Throw away uncommitted changes to a file | git restore <file> |
Yes: those changes are gone for good |
| Unstage a file but keep your changes | git restore --staged <file> |
No |
| Fix the last commit (message or a forgotten file) | git commit --amend |
No, but only do it before you push |
| Undo a commit that is already in the history | git revert <commit> |
No: it adds a new commit |
| Look at an old version of the whole project | git switch --detach <commit> |
No (return with git switch main) |
29.4.1 Throw away changes in a file: git restore
Maria wanted to add a line to README.md, but typed > instead of >>. The > overwrote the whole file:
echo "Contact page coming soon" > README.md
git diffOutput:
diff --git a/README.md b/README.md
index 9af11fc..b373488 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1 @@
-# My Awesome Project
-
-This is a simple website project to learn Git!
-
-## What it does
-
-A personal portfolio website.
-It will have a home page and a contact page.
+Contact page coming soon
Because the file was committed, Git can put it back:
git restore README.md
git statusOutput:
On branch main
nothing to commit, working tree clean
git restore <file> can’t be undone
It replaces the file with the version in the staging area (which is usually the same as the last commit). Any uncommitted changes in that file are gone for good, because they were never saved in Git.
29.4.2 Unstage a file: git restore --staged
Maria writes a personal to-do list in notes.txt and, out of habit, runs git add .:
echo "call the bank, buy milk" > notes.txt
git add .
git statusOutput:
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: notes.txt
She doesn’t want it in the project, so she takes it out of the staging area:
git restore --staged notes.txtgit status now lists notes.txt under Untracked files again. The file itself is untouched. Maria then deletes it with rm notes.txt, because it doesn’t belong in the project folder. (To keep files like this out of git status for good, see .gitignore and Keeping Secrets Out of Git.)
29.4.3 Fix the last commit: git commit --amend
In css/style.css, Maria changes the h1 rule’s color: #333; to color: navy;, then commits with a typo in the message, and fixes it right away:
git add css/style.css
git commit -m "Make headng navy"
git commit --amend -m "Make heading navy"Output (of the last command):
[main cb793da] Make heading navy
Date: Wed Oct 7 14:20:00 2026 -0400
1 file changed, 1 insertion(+), 1 deletion(-)
--amend replaces the last commit with a new one; notice the new ID. If you forgot to include a file, git add it and run git commit --amend --no-edit (which keeps the message).
Only amend commits you haven’t pushed to GitHub yet (pushing is covered in Putting Your Repository on GitHub). The online copy still has the old commit, and the two copies would disagree.
29.4.4 Undo a commit safely: git revert
Maria decides she doesn’t like the navy heading after all. git revert makes a new commit that does the exact opposite of an earlier one:
git revert --no-edit HEADOutput:
[main fc2bb9b] Revert "Make heading navy"
Date: Wed Oct 7 14:30:00 2026 -0400
1 file changed, 1 insertion(+), 1 deletion(-)
HEAD means the latest commit; you can also give any commit ID, such as git revert cb793da. --no-edit accepts the ready-made message; without it, Git opens your editor so you can edit the message first. Both commits stay in the history, so nothing is lost, and it is safe even after you’ve pushed:
git log --onelineOutput:
fc2bb9b (HEAD -> main) Revert "Make heading navy"
cb793da Make heading navy
4293e1d Add intro and contact email to home page
b90f840 Describe planned pages in README
ffd1f1f Add starter files for portfolio site
29.5 Viewing an old version: git switch --detach
To see what the whole project looked like in an earlier commit, switch to it:
git switch --detach ffd1f1fOutput:
HEAD is now at ffd1f1f Add starter files for portfolio site
Your files now look exactly as they did in that commit: src/index.html says Under construction! again. git status reports HEAD detached at ffd1f1f. Detached HEAD means you are looking at a commit directly instead of being on a branch. Look around, run the site, but don’t make commits here.
Don’t panic if git log now shows only one commit: it lists history only up to where you are. The newer commits are safe. To return:
git switch mainOutput:
Previous HEAD position was ffd1f1f Add starter files for portfolio site
Switched to branch 'main'
(git switch - also works: it goes back to the branch you were on before.)
checkout, reset)
Older tutorials, Stack Overflow answers, and AI tools often use older commands. git switch and git restore were added in 2019 (Git 2.23) to split up the jobs of git checkout, which did too many things.
| Older command | Modern equivalent |
|---|---|
git checkout -- README.md |
git restore README.md |
git reset HEAD README.md |
git restore --staged README.md |
git checkout ffd1f1f |
git switch --detach ffd1f1f |
git checkout main |
git switch main |
Be very careful with git reset --hard. git reset --hard HEAD throws away all uncommitted changes in every file at once. git reset --hard HEAD~1 also deletes the latest commit from the branch (HEAD~1 means “one commit before HEAD”). If you’ve already pushed that commit, this causes trouble. If an AI suggests git reset --hard, make sure you understand exactly what it will throw away; git revert is usually the safer choice.
To bring back an old version of a single file without moving the whole project, use git restore with --source:
git restore --source=ffd1f1f src/index.htmlThe old version replaces the file in your working directory, and git status shows the file as modified. Commit it if you want to keep it, or run git restore src/index.html to go back to the current version.
Practice Questions
Easy
Question 1 · Multiple choice
Which command lists the commits compactly, one line per commit?
git statusgit log --onelinegit diffgit show
Question 2 · True or false
git log lists the oldest commit first.
Question 3 · Short answer
Your project has 200 commits. You run git log and the output fills the screen in a viewer. How do you scroll, and how do you get back to the prompt?
Question 4 · Short answer
In the output of git diff, what do lines starting with +, -, and a space mean?
Question 5 · Matching
Match each situation with the right command.
| Situation | Command | |
|---|---|---|
1. Throw away my uncommitted changes to README.md |
A. git revert <commit> |
|
2. Take notes.txt out of the staging area |
B. git commit --amend -m "..." |
|
| 3. Fix a typo in the last commit’s message (not pushed yet) | C. git restore README.md |
|
| 4. Undo an older commit with a new commit | D. git switch --detach <commit> |
|
| 5. Look at the whole project as it was in an old commit | E. git restore --staged notes.txt |
Question 6 · True or false
git restore --staged notes.txt deletes the file notes.txt.
Medium
Question 7 · Read the diff
Describe in plain words what changed:
--- a/css/style.css
+++ b/css/style.css
@@ -4,5 +4,5 @@ body {
}
h1 {
- color: #333;
+ color: navy;
}
Question 8 · Predict the output
Maria edits src/index.html and runs git add src/index.html. What do git diff and git diff --staged show now?
Question 9 · Read the output
A diff contains the line @@ -10,4 +10,6 @@. What does it tell you?
Question 10 · Write the command
Write the command that shows the details and the diff of commit 4293e1d.
Question 11 · Write the command
Maria just committed with the message Fix typo in hedaer. She hasn’t pushed. Write the command to change the message to Fix typo in header.
Question 12 · Multiple choice
A commit that broke the site was pushed to GitHub yesterday. Which is the safest way to undo it?
git commit --amendgit revert <commit>git restore <file>- Delete the
.gitfolder and start over
Question 13 · Ordering
Put these commands in order to look at the project as it was in commit ffd1f1f and then go back to normal work:
- A.
git switch main - B.
git log --oneline(to find the commit ID) - C.
git switch --detach ffd1f1f - D. look at the files (for example
cat src/index.html)
Question 14 · Scenario
Maria runs echo "New intro" > README.md, meaning to type >>. She hasn’t run git add or git commit since. How can she recover the file, and what will happen to the line New intro?
Hard
Question 15 · Scenario
Same mistake as in the previous question, but this time Maria also ran git add . after overwriting README.md. She runs git restore README.md, but the file still says New intro. Why? How does she get the committed version back?
Question 16 · Short answer
Why should you not use git commit --amend on a commit you’ve already pushed to GitHub?
Question 17 · Scenario
Maria ran git switch --detach ffd1f1f. Now git log --oneline shows only one commit, and her contact email is gone from src/index.html. She thinks she has lost a week of work. Explain what’s going on and what she should do.
Question 18 · Compare
Compare git restore <file> and git revert <commit>: what does each one undo, does it change the history, and can you lose work?
Question 19 · Find the bug
An AI chatbot told Maria: “To undo your last commit, run git reset --hard HEAD~1.” Her last commit is already on GitHub, and she also has unsaved (uncommitted) work in css/style.css. What would this command do? What should she use instead?
Question 20 · Long answer
Explain the difference between git diff, git diff --staged, and git show. When would you use each one in your everyday workflow?