2025-02-19 Productivity, Programming
Undoing Changes & Recovering Lost Work in Git
By O. Wolfson
Working with Git can sometimes lead to mistakes like unwanted changes or lost commits. Fortunately, Git offers robust tools to revert changes and recover lost work. This article will guide you through key commands for undoing changes and reverting to previous states.
Three commands are often used to undo changes and recover lost work:
- git restore
- git reset
git revert
Each command has different purposes and behaviors.
Command | Purpose | Affects Working Directory? | Affects Staging Area (Index)? | Affects Commit History? | Common Use Case |
---|---|---|---|---|---|
git restore | Restore file(s) to a previous state | Yes (optional) | Yes (optional) | No | Discard changes in the working directory or unstage changes |
git reset | Move HEAD and optionally update index and working directory | Optional | Yes | Yes (in some modes) | Unstage changes, discard commits, or move HEAD |
git revert | Create a new commit that undoes a previous commit | No | No | Yes | Safely undo a commit in public history |
1. git restore
- Introduced in Git 2.23 to improve usability.
- Used to discard changes in the working directory or unstage changes from the index (staging area).
- Does not affect commit history.
Examples:
2. git reset
- Moves the HEAD pointer to a different commit.
- Optionally modifies the staging area and working directory depending on the mode:
--soft
: Moves HEAD, keeps changes staged.--mixed
(default): Moves HEAD, unstages changes, keeps working directory.--hard
: Moves HEAD, unstages and discards changes in working directory.
Examples:
3. git revert
- Creates a new commit that undoes the changes from a specific previous commit.
- Safe for public/shared branches because it preserves history.
- Does not modify past commits or move HEAD back.
Examples:
Key Differences Summary:
Feature | git restore | git reset | git revert |
---|---|---|---|
Undo Working Directory Changes | ✔️ | ✔️ (with --hard ) | ❌ |
Unstage Files | ✔️ | ✔️ | ❌ |
Undo Commits | ❌ | ✔️ (moves HEAD) | ✔️ (creates new commit) |
Preserves History | ✔️ | ❌ (except --soft ) | ✔️ |
Safe for Public History | ✔️ | ❌ | ✔️ |
When to Use:
Situation | Recommended Command |
---|---|
Discard changes in working directory | git restore file.txt |
Unstage a file | git restore --staged file.txt |
Undo the last commit, keep changes staged | git reset --soft HEAD~1 |
Undo the last commit, keep changes in working directory | git reset --mixed HEAD~1 |
Undo the last commit, discard changes entirely | git reset --hard HEAD~1 |
Undo a specific commit safely in shared history | git revert <commit> |
Building on the project we created earlier called my_git_project
. Let’s continue using this project to simulate common scenarios, like accidental deletions, bad commits, and recovery, so you can learn how to get back on track when things go wrong.
Recap: Setting Up my_git_project
If you haven’t already, follow these steps to create a simple project:
Create and commit a file:
Make a second change:
Now, we have a small history to work with.
🔄 Reverting to Previous Versions
Let’s say you realize that the second commit was a mistake. You want to go back to the first version.
Temporary Switch to an Earlier Commit (Checkout)
You can view the state of the project at the initial commit without changing your branch:
-
Get the commit hash for the initial commit:
Example output:
-
Temporarily switch to the first commit:
You are now in "detached HEAD" state, viewing the project as it was at the initial commit. To return to the latest state:
Permanently Go Back (Reset)
If you want to undo the second commit and erase it from history:
This will delete the second commit and any changes after it. Use this with caution—it’s permanent!
Safe Rollback Without Losing History (Revert)
Instead of erasing history, you can undo the effects of a specific commit by creating a new commit:
This will create a new commit that undoes the changes made in the second commit. The history remains intact, which is safer for shared projects.
🛠️ Undoing Commits & Changes
Sometimes, you need to undo recent work without deleting your progress.
Undo the Last Commit but Keep Changes (Soft Reset)
Let’s say you committed changes, but realized you forgot to add something. You can undo the last commit while keeping your changes staged:
This moves the commit back, but your changes stay in the staging area. You can modify files and commit again.
Undo the Last Commit and Discard Changes (Hard Reset)
If you want to completely remove the last commit and all changes:
This is irreversible—use with care.
Discard Uncommitted Changes (Restore)
If you made changes to hello.txt
but want to discard them:
This reverts the file to the last committed state. To discard all files:
🕵️ Recovering Lost Commits with git reflog
What if you made a hard reset and realize you lost important work?
- View the history of HEAD movements:
Example output:
-
Find the lost commit (e.g.,
9e2b4d2
), and recover it: -
Save it by creating a new branch:
-
Switch to this branch:
This brings your lost work back into the project.
💻 Hands-on Exercise: Simulating Accidental Deletions and Recovery
- Open
my_git_project
. - Add another line to
hello.txt
: - Realize it’s a mistake and remove the last commit:
- Panic—you needed that line!
- Use
git reflog
to find the commit hash. - Recover it:
- Create a branch to save it:
This exercise teaches you that even when things seem lost, git reflog
is your safety net.
✨ Key Takeaways
Command | Purpose |
---|---|
git checkout <commit> | Temporarily view an old commit. |
git reset --hard <commit> | Permanently move branch to a previous commit (destructive). |
git revert <commit> | Create a new commit to undo a previous commit (safe). |
git reset --soft HEAD~1 | Undo last commit but keep changes staged. |
git reset --hard HEAD~1 | Undo last commit and discard changes. |
git restore <file> | Discard changes in a file. |
git reflog | View the history of HEAD movements to recover lost commits. |
Final Thought
Mistakes are part of development. Knowing how to undo changes and recover lost work will boost your confidence in using Git. Experiment with these commands in my_git_project
to get comfortable before working on larger projects.