Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
menu
  1. Home
  2. /Web Development
  3. /Github
  4. /Undoing Changes
Your Progress0%
0 of 20 completed

Git & Github Topics

Getting Started

  • What is Git?
  • What is GitHub?
  • Installing & Configuring Git
  • Your First Git Repository

Core Git Concepts

  • Understanding Commits & History
  • Working with Branches
  • Merging Branches
  • The Staging Area
  • Undoing Changes

Working with GitHub

  • Connecting to GitHub
  • Pushing & Pulling Code
  • Cloning Repositories
  • GitHub README & Documentation

Collaboration Workflows

  • Forking & Pull Requests
  • Code Review Basics
  • Handling Merge Conflicts
  • Issues & Project Management

Best Practices & Workflows

  • Git Workflow Best Practices
  • Working with .gitignore
  • Common Git Problems & Solutions

Undoing Changes

Learn to safely undo mistakes and recover from errors in Git

Everyone makes mistakesβ€”it's part of development. The key is knowing how to fix them. Git provides powerful tools to undo changes at every stage of your workflow, from discarding uncommitted edits to safely reversing published commits. In this lesson, you'll learn the difference between git restore, git reset, and git revert, understand when to use each one, and gain the confidence to fix mistakes without fear of losing work.

Understanding "Undo" in Git

Git has multiple commands for undoing changes, each designed for different scenarios:

  • git restore: Discard changes in working directory or unstage files
  • git reset: Move branch pointer to a different commit (rewrite history)
  • git revert: Create a new commit that undoes a previous commit (preserve history)

The command you choose depends on what you want to undo and whether you've shared your changes.

🎯 The Golden Rule

Never rewrite history that has been pushed to a shared repository.

If others have your commits, use git revert (safe). If commits are only local, you can use git reset (rewrites history).

Which Undo Command Should I Use?

Here's a decision tree to help you choose:

TEXT
What do you want to undo?

β”œβ”€ Uncommitted changes to a file
β”‚  └─ Use: git restore filename
β”‚
β”œβ”€ Staged changes (unstage but keep edits)
β”‚  └─ Use: git restore --staged filename
β”‚
β”œβ”€ Last commit (not pushed)
β”‚  β”œβ”€ Keep changes staged
β”‚  β”‚  └─ Use: git reset --soft HEAD~1
β”‚  β”œβ”€ Keep changes unstaged
β”‚  β”‚  └─ Use: git reset HEAD~1  (or --mixed)
β”‚  └─ Discard changes completely
β”‚     └─ Use: git reset --hard HEAD~1
β”‚
└─ Commit that's been pushed
   └─ Use: git revert commit-hash

Git Restore: Discarding Changes

git restore is the modern, clear way to discard changes or unstage files. It was introduced in Git 2.23 to split the confusinggit checkout command into separate, clear commands.

Discard Uncommitted Changes

Throw away changes in your working directory:

BASH
# Discard changes to a specific file
git restore filename.txt

# Discard changes to multiple files
git restore file1.txt file2.txt

# Discard all changes in current directory
git restore .

Warning: This permanently deletes your uncommitted changes! They cannot be recovered. Make sure you really want to discard them.

Example: Discard Unwanted Changes

BASH
# You edited index.html but don't like the changes
git status
# modified:   index.html

# Discard the changes
git restore index.html

# File is back to last committed version
git status
# nothing to commit, working tree clean

Unstage Files

Remove files from staging area without discarding changes:

BASH
# Unstage a specific file
git restore --staged filename.txt

# Unstage all files
git restore --staged .

Example: Unstage Accidentally Staged Files

BASH
# You staged everything, including debug files
git add .

# Check what's staged
git status
# Changes to be committed:
#   modified:   app.js
#   modified:   debug.js  ← Don't want this

# Unstage just the debug file
git restore --staged debug.js

# Now debug.js is modified but not staged
git status
# Changes to be committed:
#   modified:   app.js
# Changes not staged for commit:
#   modified:   debug.js

Restore a File from a Specific Commit

BASH
# Restore a file to how it was in a specific commit
git restore --source=a1b2c3d filename.txt

# Restore a file from 3 commits ago
git restore --source=HEAD~3 filename.txt

Git Reset: Moving the Branch Pointer

git reset moves your current branch pointer to a different commit. This effectively "undoes" commits by making your branch point to an earlier state.

Important: git reset rewrites history. Only use it on commits that haven't been pushed!

The Three Types of Reset

1. Soft Reset (--soft)

Moves HEAD but keeps all changes staged:

BASH
git reset --soft HEAD~1

What it does:

  • βœ… Moves branch pointer back one commit
  • βœ… Keeps all changes in staging area
  • βœ… Keeps working directory unchanged

Use case: You want to redo the last commit with a different message or add more changes to it.

BASH
# Made a commit with a typo in the message
git commit -m "Add usr authentication"  # Oops, "usr" should be "user"

# Undo the commit but keep changes staged
git reset --soft HEAD~1

# Fix the message
git commit -m "Add user authentication"

2. Mixed Reset (--mixed, default)

Moves HEAD and unstages changes (but keeps them in working directory):

BASH
git reset HEAD~1
# or explicitly:
git reset --mixed HEAD~1

What it does:

  • βœ… Moves branch pointer back one commit
  • βœ… Unstages changes (removes from staging area)
  • βœ… Keeps changes in working directory

Use case: You want to undo a commit and rethink what to stage.

BASH
# Committed too many files together
git commit -m "Multiple changes"

# Undo commit, keep changes unstaged
git reset HEAD~1

# Now selectively stage and commit separately
git add feature.js
git commit -m "Add new feature"

git add bugfix.js
git commit -m "Fix bug in login"

3. Hard Reset (--hard)

Moves HEAD and discards all changes:

BASH
git reset --hard HEAD~1

What it does:

  • βœ… Moves branch pointer back one commit
  • ❌ Discards staged changes
  • ❌ Discards working directory changes

DANGER: git reset --hard permanently deletes uncommitted work! Only use it when you're absolutely sure you want to discard everything.

Use case: You want to completely abandon recent work and start fresh.

BASH
# You went down the wrong path
git log --oneline
# a1b2c3d (HEAD -> main) Wrong approach
# f4e5d6c Another mistake
# c7d8e9f This was good ← Want to go back here

# Completely reset to c7d8e9f
git reset --hard c7d8e9f

# Everything after c7d8e9f is gone

Reset Comparison

TEXT
Starting point: You have a commit you want to undo

                Working Dir  Staging Area  Repository
--soft          Keep         Keep          Change
--mixed         Keep         Clear         Change
--hard          Clear        Clear         Change

πŸ’‘ Remember the Reset Types

Think of it as levels of "forgetfulness":

  • --soft: Git forgets the commit, remembers everything else
  • --mixed: Git forgets the commit and staging, remembers your edits
  • --hard: Git forgets everything (commit, staging, edits)

Git Revert: Safe History Preservation

git revert creates a new commit that undoes changes from a previous commit. Unlike git reset, it doesn't rewrite historyβ€”it adds to it.

How Revert Works

TEXT
Before revert:
A --- B --- C --- D  (main)

After reverting commit C:
A --- B --- C --- D --- E  (main)
                        ↑
                    (reverts C's changes)

Commit E is a new commit that undoes everything commit C did. If C added lines, E removes them. If C deleted lines, E adds them back.

Basic Revert

BASH
# Revert the last commit
git revert HEAD

# Revert a specific commit
git revert a1b2c3d

# Revert multiple commits
git revert HEAD~3..HEAD

Example: Revert a Pushed Commit

BASH
# You pushed a bug to production
git log --oneline
# a1b2c3d (HEAD -> main, origin/main) Add new feature (BUG!)
# f4e5d6c Previous commit
# c7d8e9f Earlier commit

# Can't use reset because others have this commit
# Use revert instead
git revert a1b2c3d

# Git opens editor for revert commit message:
# "Revert 'Add new feature'"
# Save and close

# New commit created that undoes the bug
git log --oneline
# b0a1c2d (HEAD -> main) Revert "Add new feature"
# a1b2c3d (origin/main) Add new feature (BUG!)
# f4e5d6c Previous commit

# Push the revert
git push

# The bug is now undone, history is preserved

Revert Without Opening Editor

BASH
# Use --no-edit to skip editing the message
git revert HEAD --no-edit

# Or provide a custom message
git revert a1b2c3d -m "Revert feature X due to bug"

Revert and Continue Editing

BASH
# Start revert but don't commit yet
git revert a1b2c3d --no-commit

# Make additional changes if needed
# Then commit when ready
git commit -m "Revert feature X and update docs"

When to Use Revert vs Reset

Use git revert when:

  • The commit has been pushed to a shared repository
  • Other people might have the commit
  • You want to preserve complete history
  • You're working on a public/shared branch

Use git reset when:

  • The commit exists only on your local machine
  • You haven't pushed yet
  • You're working on a private branch
  • You want a cleaner history

Practical Undo Scenarios

Scenario 1: Fix a Bad Commit Message

BASH
# Just committed with wrong message
git commit -m "Fix bg"  # Oops, meant "bug"

# Amend the commit message
git commit --amend -m "Fix bug in login validation"

# Or open editor to write better message
git commit --amend

Scenario 2: Forgot to Add Files to Commit

BASH
# Made a commit but forgot a file
git commit -m "Add user profile page"

# Oops, forgot profile.css
git add profile.css

# Add to the previous commit
git commit --amend --no-edit

# The forgotten file is now part of the last commit

Scenario 3: Committed to Wrong Branch

BASH
# You're on main but should be on feature branch
git log --oneline
# a1b2c3d (HEAD -> main) New feature (WRONG BRANCH!)

# Create feature branch pointing to current commit
git branch feature/new-feature

# Reset main to before the commit
git reset --hard HEAD~1

# Switch to the feature branch
git switch feature/new-feature

# Commit is now on the right branch!

Scenario 4: Undo Multiple Commits

BASH
# You want to undo the last 3 commits
git log --oneline
# a1b2c3d (HEAD -> main) Third commit
# f4e5d6c Second commit
# c7d8e9f First commit
# b0a1c2d Good commit ← Want to go back here

# Option 1: Reset (if not pushed)
git reset --soft HEAD~3
# All 3 commits undone, changes still staged

# Option 2: Reset and discard
git reset --hard HEAD~3
# All 3 commits and changes discarded

# Option 3: Revert (if pushed)
git revert HEAD~2..HEAD
# Creates 3 new commits that undo the changes

Scenario 5: Recover Deleted Files

BASH
# Accidentally deleted a file
rm important.txt

# Restore it from last commit
git restore important.txt

# Or if you committed the deletion
git log --oneline -- important.txt
# Find the last commit where it existed: f4e5d6c

# Restore from that commit
git restore --source=f4e5d6c important.txt

Scenario 6: Undo Staged Changes

BASH
# Staged too many files
git add .

# Unstage specific file
git restore --staged debug.js

# Or unstage everything
git restore --staged .

Recovering "Lost" Commits

Even after resetting or losing commits, Git keeps them for a while. You can recover them using git reflog.

What is Reflog?

The reflog (reference log) records every time HEAD movesβ€”every commit, reset, checkout, etc. It's like an undo history for Git itself.

BASH
# View reflog
git reflog
TEXT
a1b2c3d HEAD@{0}: reset: moving to HEAD~3
f4e5d6c HEAD@{1}: commit: Third commit
c7d8e9f HEAD@{2}: commit: Second commit
b0a1c2d HEAD@{3}: commit: First commit

Recover a Reset Commit

BASH
# You did a hard reset and regret it
git reset --hard HEAD~3

# Oh no! Want those commits back
# Check reflog
git reflog

# Find the commit before the reset
# f4e5d6c HEAD@{1}: commit: Third commit

# Reset to that commit
git reset --hard f4e5d6c

# Your commits are back!

πŸ”’ Git Keeps Everything

Git keeps "lost" commits for about 30 days (90 days for referenced commits). During this time, you can usually recover them using reflog!

Traditional Commands (Still Widely Used)

Before git restore (Git 2.23), people used git checkout and git reset for these operations. You'll still see these in tutorials and scripts:

Old vs New Commands

BASH
# Discard changes to a file
git checkout -- filename      # Old way
git restore filename          # New way

# Unstage a file
git reset HEAD filename       # Old way
git restore --staged filename # New way

# Switch branches
git checkout branch-name      # Old way
git switch branch-name        # New way

Both work, but the new commands are clearer about what they do.

Practice Undo Commands

Try these commands to practice undoing changes safely:

Practice Undoing Changes

Experiment with restore, reset, and viewing history

$

Try these examples:

Safety Tips for Undoing Changes

1. Always Check Status First

BASH
# Before any undo operation
git status
git log --oneline -5

# Know what state you're in!

2. Use Soft Reset When Unsure

If you're not sure, use --soft first. You can always go harder later:

BASH
# Safe: keeps everything
git reset --soft HEAD~1

# Check if this is what you want
git status

# If yes, commit again
# If no, continue with --mixed or --hard

3. Create a Backup Branch

BASH
# Before risky operations, create a backup
git branch backup-before-reset

# Do your reset
git reset --hard HEAD~5

# Oops, that was wrong?
git reset --hard backup-before-reset

# Crisis averted!

4. Use Revert for Published Commits

Never reset commits that have been pushed!

Use git revert instead. Resetting shared history causes major problems for collaborators.

5. Understand What You're Undoing

BASH
# Before resetting, see what you're about to undo
git show HEAD
git diff HEAD~3..HEAD

# Make sure you understand what will be lost

Command Reference

Here's a quick reference of all undo commands:

BASH
# Discard Changes (Working Directory)
git restore filename              # Discard changes to file
git restore .                     # Discard all changes
git restore --source=abc123 file  # Restore from specific commit

# Unstage Changes (Staging Area)
git restore --staged filename     # Unstage specific file
git restore --staged .            # Unstage all files

# Amend Last Commit
git commit --amend                # Change last commit message
git commit --amend --no-edit      # Add files to last commit

# Reset (Move Branch Pointer)
git reset --soft HEAD~1           # Undo commit, keep staged
git reset HEAD~1                  # Undo commit, keep unstaged
git reset --hard HEAD~1           # Undo commit, discard changes
git reset --hard abc123           # Reset to specific commit

# Revert (Create New Commit)
git revert HEAD                   # Revert last commit
git revert abc123                 # Revert specific commit
git revert HEAD~3..HEAD           # Revert multiple commits
git revert abc123 --no-commit     # Revert but don't commit yet

# Recovery
git reflog                        # View HEAD movement history
git reset --hard abc123           # Recover "lost" commit

# Traditional Commands (Still Work)
git checkout -- filename          # Old: discard changes
git reset HEAD filename           # Old: unstage file
git checkout branch               # Old: switch branch

Key Takeaways

  • git restore discards changes or unstages files
  • git reset moves branch pointer and rewrites history (local only!)
  • git revert creates new commits to undo previous ones (safe for shared history)
  • --soft keeps changes staged, --mixed unstages them, --hard discards them
  • Never reset commits that have been pushed to shared repositories
  • git reflog can recover "lost" commits for ~30 days
  • git commit --amend fixes the most recent commit
  • Always check status before undoing operations
  • Create backup branches before risky operations
  • When in doubt, use the safest option first (--soft or revert)

What's Next?

Congratulations! You've completed the Core Git Concepts section. You now understand commits, branches, merging, the staging area, and how to undo changes. These are the fundamental skills that every Git user needs.

In the next section, we'll start Working with GitHub. You'll learn how to connect your local Git repositories to GitHub, push and pull code, collaborate with others, and use GitHub's powerful features. This is where your local Git knowledge meets the world of collaborative development!

🎯 Practice Assignment

Before moving to GitHub, practice undoing changes:

  1. Make several commits in a test repository
  2. Practice using git reset --soft, --mixed, and --hard
  3. Try reverting a commit with git revert
  4. Intentionally "lose" a commit and recover it with git reflog
  5. Practice amending commits with git commit --amend
  6. Use git restore to discard changes and unstage files

The more comfortable you are fixing mistakes, the more confident you'll be using Git!

Test Your Understanding of Undoing Changes

Question 1 of 4

What's the safest way to discard uncommitted changes to a file?

Current Score0 / 0

Know someone who'd find this guide helpful? Please share!

Previous
The Staging Area
Next
Connecting to GitHub

Never Miss a New Git & GitHub Tutorial

Join 2,000+ developers learning Git & GitHub step-by-step. Get new tutorials, tips, and exclusive resources delivered to your inbox - completely FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

Git & Github Tutorials

0 of 20 completed

Your Progress0%

Topics

Getting Started

  • What is Git?
  • What is GitHub?
  • Installing & Configuring Git
  • Your First Git Repository

Core Git Concepts

  • Understanding Commits & History
  • Working with Branches
  • Merging Branches
  • The Staging Area
  • Undoing Changes

Working with GitHub

  • Connecting to GitHub
  • Pushing & Pulling Code
  • Cloning Repositories
  • GitHub README & Documentation

Collaboration Workflows

  • Forking & Pull Requests
  • Code Review Basics
  • Handling Merge Conflicts
  • Issues & Project Management

Best Practices & Workflows

  • Git Workflow Best Practices
  • Working with .gitignore
  • Common Git Problems & Solutions
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

Β© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo