Undoing Changes Safely: git restore, git reset, and git revert0%

Undoing Changes Safely: git restore, git reset, and git revert

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

Undoing Changes Safely: git restore, git reset, and git revert

Making mistakes is an inevitable part of programming. Git's greatest strength is its ability to undo almost any action. However, because different undo commands have vastly different consequences, understanding when to use git restore, git reset, or git revert is critical to avoiding accidental data loss.


1. Decision Matrix: Which Undo Command Should You Use?

Output
What do you want to undo?
|
+---> 1. Unstaged changes in Working Directory? ---------> `git restore <file>`
|
+---> 2. Staged changes in Index? -----------------------> `git restore --staged <file>`
|
+---> 3. Local unpushed commit(s) on your machine? ------> `git reset` (soft / mixed / hard)
|
+---> 4. Commit already pushed to a shared remote repo? -> `git revert <commit-hash>`

2. Modern Undoing in the Working Tree: git restore

Introduced in Git 2.23, git restore is designed for safety:

Bash / Terminal
# 1. Discard uncommitted changes in a specific file (IRREVERSIBLE!)
git restore index.html
 
# 2. Discard all uncommitted changes across entire working tree
git restore .
 
# 3. Unstage a file (moves it out of Staging Area back to modified in working tree)
git restore --staged package.json

3. Rewinding Local History: git reset

git reset moves the current branch pointer backward in time. It has three distinct modes:

Output
(C1) <--- (C2) <--- (C3) [HEAD, main]
^
|
Command: git reset HEAD~1

The Three Modes of git reset:

ModeMoves Branch Pointer Back?Keeps Changes in Staging Area?Keeps Changes in Working Directory?Safety Level
--softYesYes (Staged)YesCompletely Safe
--mixed (default)YesNo (Unstaged)YesSafe
--hardYesNoNo (Destroyed!)DANGEROUS!

Practical Examples:

Bash / Terminal
# Undo the last commit, but KEEP all modified files staged in index:
git reset --soft HEAD~1
 
# Undo the last commit and unstage files, but keep edits on disk in working tree:
git reset HEAD~1
 
# Completely obliterate the last commit and wipe out all local file modifications:
git reset --hard HEAD~1
Important Warning
[!CAUTION] git reset --hard permanently discards uncommitted work in your working tree. There is no undo for uncommitted files lost to --hard!

4. The Collaborative Safe Undo: git revert

[!IMPORTANT] Golden Rule of Git: Never use git reset on commits that have already been pushed to a shared public branch (like main)! Resetting rewrites history and breaks other developers' clones.

Instead, use git revert:

  • git revert does not erase the bad commit from history.
  • Instead, it creates a brand new commit that introduces the exact opposite mathematical inverse of the bad commit!
Output
Before Revert:
(C1) ---> (C2: Introduced payment bug) ---> (C3) [main, origin/main]
 
Command: git revert C2
 
After Revert:
(C1) ---> (C2: Bug) ---> (C3) ---> (C4: Revert "Introduced payment bug") [main]

Because history is purely additive, git revert is 100% safe for pushed production branches.


Interactive Quiz

Practice Quiz

Question 1
Which command safely discards uncommitted changes in app.js in your working directory?
Question 2
What is the effect of running git reset --soft HEAD~1?
Question 3
Why is git reset --hard considered a dangerous command?
Question 4
If a buggy commit has already been pushed to a shared team branch on GitHub, what is the best command to undo it?
Question 5
What does git restore --staged <file> do?
Next Lesson

Rebasing Branches: Linear History with git rebase vs git merge

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext