9. Undoing Changes & Fixing Mistakes

It is inevitable: at some point, you will make a mistake. You might write bad code, delete a useful file, stage the wrong file, or commit changes you didn't mean to. Fortunately, one of Git's best aspects is that **almost everything is reversible**. In this chapter, we will learn how to undo mistakes at every step of your workflow.

1. Undoing Working Directory Changes: git restore

If you have made modifications to a file in your Working Directory, but have not staged it yet, and want to discard those changes and return the file to its last committed state:

# Discard changes in a specific file
git restore index.html

# Discard changes in the entire current directory
git restore .
Warning: git restore in the working directory is **destructive and permanent**. Since the discarded changes were never committed, Git cannot recover them!

2. Unstaging a File: git restore --staged

If you accidentally staged a file (using git add) and want to remove it from the Staging Area, but *keep* the actual code changes safe in your Working Directory:

git restore --staged index.html

This pulls the file out of the Staging Area, making it a normal unstaged modification.

3. Undoing Commits: git reset

If you committed changes locally but want to undo that commit, you can use git reset. There are three flavors of reset, depending on what you want to do with your working files:

Reset TypeCommandWhat happens to your files?
Soft Resetgit reset --soft HEAD~1Undoes the commit. All modifications remain intact and **remain staged** in the Staging Area. Highly safe.
Mixed Reset (Default)git reset --mixed HEAD~1Undoes the commit and unstages all files. All modifications remain intact in your **Working Directory** but are unstaged.
Hard Resetgit reset --hard HEAD~1Destructive! Undoes the commit, unstages the files, and **wipes out all modifications** from your filesystem.

4. Safe Undoing on Shared Repos: git revert

Using git reset rewrites history by erasing commits. If you have already pushed commits to a shared team repository, erasing history will break other developers' setups. To undo changes safely on shared branches, use git revert:

git revert a8f1b2c

Unlike reset, git revert **does not erase** the commit a8f1b2c. Instead, it calculates the exact opposite of that commit and creates a **brand new commit** that rolls back the changes. This preserves history and is perfectly safe for collaborative repositories!