15 minworkshop

Undo & Recovery Workshop

Undo & Recovery Workshop

Practice recovering from common Git mistakes. Each exercise simulates a real scenario you might encounter.

Setup

Create a repository with some history:

bash
1$ mkdir undo-practice && cd undo-practice
2$ git init
3
4$ echo "Line 1" > file.txt
5$ git add file.txt
6$ git commit -m "first commit"
7
8$ echo "Line 2" >> file.txt
9$ git add file.txt
10$ git commit -m "second commit"
11
12$ echo "Line 3" >> file.txt
13$ git add file.txt
14$ git commit -m "third commit"

Check the history:

bash
1$ git log --oneline
2abc1234 third commit
3def5678 second commit
4ghi9012 first commit

Exercise 1: Unstage a File

Scenario

You accidentally staged a file you didn't mean to include.

bash
1$ echo "debug info" > debug.log
2$ git add debug.log
3$ git status
4Changes to be committed:
5 new file: debug.log

Solution

bash
1$ git restore --staged debug.log
2
3$ git status
4Untracked files:
5 debug.log

The file is unstaged but still exists.

Verify

bash
1$ cat debug.log
2debug info

Exercise 2: Discard Local Edits

Scenario

You made changes to a file but want to revert to the committed version.

bash
1$ echo "BAD CHANGE" > file.txt
2$ cat file.txt
3BAD CHANGE
4
5$ git status
6Changes not staged for commit:
7 modified: file.txt

Solution

bash
1$ git restore file.txt
2
3$ cat file.txt
4Line 1
5Line 2
6Line 3

The file is restored to its committed state.

Exercise 3: Undo Last Commit (Keep Changes)

Scenario

You committed too early and want to add more to the commit.

bash
1$ echo "Line 4" >> file.txt
2$ git add file.txt
3$ git commit -m "incomplete commit"
4
5$ git log --oneline
6xyz0001 incomplete commit
7abc1234 third commit
8...

Solution

bash
1$ git reset --soft HEAD~1
2
3$ git status
4Changes to be committed:
5 modified: file.txt
6
7$ git log --oneline
8abc1234 third commit
9def5678 second commit
10ghi9012 first commit

The commit is undone, but changes are still staged.

Complete the Exercise

bash
1$ echo "Line 5" >> file.txt
2$ git add file.txt
3$ git commit -m "complete commit with lines 4 and 5"

Exercise 4: Undo Last Commit (Unstage Changes)

Scenario

You want to undo a commit and reorganize what goes in it.

bash
1$ git log --oneline
2xyz0002 complete commit with lines 4 and 5
3abc1234 third commit
4...

Solution

bash
1$ git reset HEAD~1
2
3$ git status
4Changes not staged for commit:
5 modified: file.txt

Changes are in the working tree but unstaged.

Recommit

bash
1$ git add file.txt
2$ git commit -m "properly organized commit"

Exercise 5: Hard Reset to Remote

Scenario

Your local main has diverged and you want to match origin exactly.

First, simulate divergence:

bash
1$ echo "Local only change" >> local.txt
2$ git add local.txt
3$ git commit -m "local commit that should not exist"

Solution

Since we don't have a real remote, simulate with a tag:

bash
1# Mark the "good" state
2$ git tag good-state HEAD~1
3
4# Reset to it (simulating reset to origin/main)
5$ git reset --hard good-state
6
7$ git log --oneline
8# The "local commit" is gone

In real usage:

bash
1$ git reset --hard origin/main

Exercise 6: Revert a Deployed Bug

Scenario

A commit introduced a bug, but it's already pushed and deployed.

bash
1$ echo "BUGGY CODE" >> file.txt
2$ git add file.txt
3$ git commit -m "feat: introduce bug"
4
5$ git log --oneline
6bug1234 feat: introduce bug
7...

Solution

bash
1$ git revert HEAD
2# Editor opens for commit message
3# Save and close
4
5$ git log --oneline
6rev5678 Revert "feat: introduce bug"
7bug1234 feat: introduce bug
8...
9
10$ cat file.txt
11# BUGGY CODE line is removed

The bug is undone with a new commit, preserving history.

Exercise 7: Find Lost Work with Reflog

Scenario

You accidentally reset and lost commits.

bash
1# Create a commit
2$ echo "Important work" >> important.txt
3$ git add important.txt
4$ git commit -m "important work"
5
6# Accidentally lose it
7$ git reset --hard HEAD~1
8
9$ git log --oneline
10# "important work" commit is gone!

Solution

bash
1$ git reflog
2abc1234 HEAD@{0}: reset: moving to HEAD~1
3imp5678 HEAD@{1}: commit: important work
4...
5
6# Recover the commit
7$ git reset --hard imp5678
8
9$ git log --oneline
10imp5678 important work
11...
12
13$ cat important.txt
14Important work

The lost work is recovered!

Exercise 8: Recover a Deleted Branch

Scenario

You deleted a branch before merging.

bash
1# Create and commit on a branch
2$ git checkout -b feature/oops
3$ echo "Feature code" > feature.txt
4$ git add feature.txt
5$ git commit -m "add feature"
6
7# Switch and delete
8$ git checkout main
9$ git branch -D feature/oops
10Deleted branch feature/oops (was feat123).

Solution

bash
1$ git reflog
2abc1234 HEAD@{0}: checkout: moving from feature/oops to main
3feat123 HEAD@{1}: commit: add feature
4...
5
6# Recreate the branch
7$ git branch feature/recovered feat123
8
9$ git checkout feature/recovered
10$ cat feature.txt
11Feature code

Branch recovered!

Cleanup

bash
1$ cd ..
2$ rm -rf undo-practice

Checklist

  • Unstaged a file with git restore --staged
  • Discarded local edits with git restore
  • Used soft reset to undo a commit but keep changes staged
  • Used mixed reset to undo a commit and unstage changes
  • Used hard reset to completely discard changes
  • Reverted a commit to preserve history
  • Used reflog to recover a lost commit
  • Used reflog to recover a deleted branch

Summary Table

ScenarioCommand
Unstage filegit restore --staged file
Discard editsgit restore file
Undo commit, keep stagedgit reset --soft HEAD~1
Undo commit, keep unstagedgit reset HEAD~1
Undo commit, discard allgit reset --hard HEAD~1
Undo pushed commitgit revert SHA
Find lost workgit reflog

Key Takeaway

Every Git mistake is recoverable if you know the right command. Always check git reflog before giving up on lost work—Git rarely forgets.