↩️ Undoing things safely

A ladder of undo tools, from gentle to sharp, and why committed work almost never dies.

1First, the good news

Everyone breaks something eventually. You will too, and that is fine. Here is the most comforting fact in all of git: once a photo is in the album, it is almost impossible to truly lose. Git hoards everything. Even photos you think you threw away usually still exist in the album's back pocket.

The genuinely risky moments all happen before the photo is taken. Edits sitting in a file that was never committed have no photo to fall back on. Keep that in mind as we climb the undo ladder, starting with the gentlest tool and ending at the sharp drawer you should barely touch.

2"I typo'd my last commit message, or forgot a file"

You took a photo two minutes ago, and the sticky note says "tdoo update". Or one file missed the basket. No need for a second, apologetic photo. You can simply retake the last one.

🗣 Git's word for retaking the last photo is "amend". git commit --amend swaps your newest commit for a fresh one. Forgot a file? Put it in the basket with git add first, then amend. The new photo includes everything in the basket plus the old photo's contents.

Here is what it looks like with your own latest save point. Imagine the note had come out wrong:

# the newest photo in your album, with a typo on the sticky note
$ git log --oneline -1
f30f6b7 tdoo update
$ git commit --amend -m "todo update"
[main 9c1e4d2] todo update
$ git log --oneline -1
9c1e4d2 todo update
# same work, retaken photo, brand new receipt number
⚠️ Amend does not edit the old photo. It takes a brand new one and discards the old, so the receipt number changes. That is harmless on your own machine. But if you already pushed that commit (pushing sends your commits to a shared copy on GitHub, the subject of Lesson 9), other people have copies of the old photo, and swapping yours out makes the albums disagree. Only amend commits you have not pushed or shared yet.

⌨️ Try it yourself

In your playground folder, make a typo on purpose, then fix it with amend:

cd /tmp/git-playground
echo "undo practice" >> notes.txt
git add notes.txt
git commit -m "tdoo update"      # typo on purpose
git commit --amend -m "todo update"
git log --oneline -1             # one tidy photo, new receipt number

3"I ruined a file but never committed"

You opened notes.txt, experimented bravely, and now it is a mess. You have not taken a photo since the damage. You just want the file back the way it was.

🗣 Git's word for repainting a file from the last photo is "restore". git restore notes.txt puts the file back exactly the way the most recent photo shows it. Your messy edits vanish, and the photographed version returns.
$ git restore notes.txt
$ git status
nothing to commit, working tree clean
⚠️ Of all the everyday undo tools, this is the one that truly destroys work. Your messy edits were never photographed, so there is nothing to recover them from. git restore discards them forever. That is the whole moral of this lesson: commit often. Photos are free, and anything photographed is nearly unlosable.

⌨️ Try it yourself

Ruin the file on purpose, then watch the last photo bring it back:

echo "total garbage" > notes.txt   # ruin it
cat notes.txt
git restore notes.txt
cat notes.txt                    # back to the last photo

4"A bad commit is already shared"

📷 You cannot un-take a photo that everyone already has copies of. Once a photo is pushed, your teammates have it in their albums too. Ripping it out of your album does not rip it out of theirs. But you can publish a correction photo that says: ignore that one, here is the fix.
🗣 Git's word for the correction photo is "revert". git revert <sha> takes a NEW photo that is the exact opposite of the bad one. If the bad commit added a line, the revert removes it. History only grows forward, nothing is erased, and nobody's album ever disagrees with anybody else's.
$ git revert b4dc0de
[main e7a9f12] Revert "oops"
 1 file changed, 1 deletion(-)
# a new photo that cancels the bad one
The safe way: revert adds a correction photo A B C oops D undo C the opposite of C The tempting way: rip C out of the album A B C rewriting shared history: don't

Notice what the safe way does not do: C is still in the chain. The album simply gained one more bead, and anyone who syncs gets D. The problem is gone, the story is honest, and nobody is confused.

5The safety net: reflog

One day you will switch branches, undo something, switch again, and look up with no idea where your work went. Git keeps a private diary for exactly this moment.

🗣 Git's word for that diary is the "reflog". git reflog lists every place your "you are here" marker has been recently, even moves caused by mistakes. Each line comes with a receipt number you can jump back to.
$ git reflog
9c1e4d2 HEAD@{0}: commit (amend): todo update
f30f6b7 HEAD@{1}: commit: tdoo update
db039fb HEAD@{2}: commit: review fixes
836f2de HEAD@{3}: checkout: moving from launch-plan to main
fb9fecb HEAD@{4}: commit: launch tracking
# every line is a place you have been, with its receipt number.
# even the typo photo you amended away in section 2 is still here!

Find the line from back when life was good, then rescue that spot onto a fresh bookmark:

$ git switch -c rescue 836f2de
Switched to a new branch 'rescue'

Older guides write git checkout -b rescue 836f2de. Checkout is the older word for the same move. Put the reflog together with the fact that commits are almost unlosable, and the conclusion is calming: a wrong turn is nearly always recoverable.

6The sharp tools drawer

Two commands live at the bottom of the ladder. You will meet them in other people's advice long before you need them.

⚠️ git reset --hard and git push --force have legitimate uses, and they are the two commands that can destroy work even after the photo was taken, yours or a teammate's. Beginner rule: if a command needs --hard or --force, stop and double-check with someone first. There is almost always a gentler rung on the ladder that does the job.

7Which tool, when?

SituationTool
Typo in the last commit message, or forgot a filegit commit --amend
Ruined a file, never committed the messgit restore <file>
A bad commit is already sharedgit revert <sha>
"Where was I before this mess?"git reflog

Q. A bad commit was pushed and your teammates already pulled it. What is the safest fix?

Revert takes a new photo that cancels the bad one. Nothing is erased, so your album and your teammates' albums never disagree.

Why is revert safer than erasing the commit?

Because your teammates' copies of the album still contain the erased photo. If you erase it only on your side, the albums disagree, and the next sync turns into chaos. Adding the opposite photo keeps every copy consistent and tells the story honestly: we made a mistake, and here is the fix.
🧠 If you remember one thing: before the photo your work is fragile (restore discards it for real); after the photo it is nearly indestructible (amend fixes it locally, revert fixes it publicly, and reflog finds everything).