Post

04 - Fixing Mistakes

#04 - Fixing Mistakes

##The Good News

Git is designed to be nearly impossible to permanently lose work — as long as you committed it. This module teaches you how to undo mistakes at every stage of the workflow.

The key question is always: how far has the mistake gone?

1
2
3
Stage 1: Wrong file staged (but not committed yet)    easiest to fix
Stage 2: Wrong file committed (but not pushed)        still easy
Stage 3: Need to understand what went wrong           use git log / git diff

##Mistake 1: Staged the Wrong File

The situation: You ran git add on the wrong file (or more files than you meant to). You have not committed yet.

Let’s recreate it:

1
2
3
4
5
6
7
8
9
10
11
12
13
mkdir practice && cd practice && git init

touch good_file.py bad_file.py
git add good_file.py
git commit -m "add good_file"

#Now make changes to both files
echo "good code" > good_file.py
echo "oops not ready" > bad_file.py

#Accidentally stage both
git add good_file.py bad_file.py
git status

Expected:

1
2
3
Changes to be committed:
    modified: bad_file.py
    modified: good_file.py

Fix — unstage bad_file.py:

1
2
git restore --staged bad_file.py
git status

Expected:

1
2
3
4
5
Changes to be committed:
    modified: good_file.py

Changes not staged for commit:
    modified: bad_file.py

bad_file.py is back in the working directory — unchanged, just unstaged. Now commit only what you intended:

1
git commit -m "Update good_file with new logic"

git restore --staged <file> is the modern command (Git 2.23+). The older equivalent is git reset HEAD <file> — both do the same thing.

Unstage everything at once:

1
git restore --staged .

##Mistake 2: Committed the Wrong File

The situation: You committed something you should not have. The commit is in your local history but you have NOT pushed yet.

1
2
3
4
5
6
#Simulate the mistake
echo "SECRET_KEY=abc123" > .env
git add .env
git commit -m "add config file"

git log --oneline

Expected:

1
2
f8a3c1b add config file       the bad commit
9d2e4a0 add good_file

Fix — undo the last commit but keep the file:

1
2
git reset --soft HEAD~1
git status

Expected:

1
2
Changes to be committed:
    new file: .env

The commit is gone from history, but .env is still staged. Now unstage it and decide what to do:

1
2
git restore --staged .env
git status

Expected:

1
2
Untracked files:
    .env

Add .env to .gitignore so this never happens again:

1
2
3
echo ".env" >> .gitignore
git add .gitignore
git commit -m "Add .gitignore to exclude .env"

##Understanding Reset Modes: Soft vs Hard

git reset moves the HEAD pointer back to a previous commit. The three modes differ in what they do to your files after moving.

###The Three Areas (refresher)

1
Working Directory    Staging Area    Repository (commits)

###–soft: Undo commit, keep changes staged

HEAD moves back, but your files stay staged. Perfect for “I committed too soon, let me add one more thing first.”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#Make two commits
echo "line 1" > notes.txt && git add notes.txt && git commit -m "add line 1"
echo "line 2" >> notes.txt && git add notes.txt && git commit -m "add line 2"

git log --oneline
#f1a2b3c add line 2
#a4b5c6d add line 1

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

git log --oneline
#a4b5c6d add line 1     last commit is gone

git status
#Changes to be committed:
#    modified: notes.txt     but the change is still staged!

Use --soft when you want to recommit with a better message, or combine with the next commit.

###–mixed (default): Undo commit AND unstage

HEAD moves back and the staging area is cleared, but your file edits remain.

1
2
3
4
5
6
git reset HEAD~1
#same as: git reset --mixed HEAD~1

git status
#Changes not staged for commit:
#    modified: notes.txt     change is in working dir, not staged

Use --mixed when you want to re-review and re-stage your changes before committing.

###–hard: Undo commit AND discard all changes

HEAD moves back, staging is cleared, AND your working directory is reverted. The changes are gone.

1
2
3
4
git reset --hard HEAD~1

git status
#nothing to commit, working tree clean     changes are GONE

Use --hard only when you are 100% sure you want to throw away those changes.

###Comparison Table

Mode HEAD moves Staging area Working directory
--soft back unchanged (still staged) unchanged
--mixed (default) back cleared unchanged
--hard back cleared reverted — changes lost

###Practical decision guide

1
2
3
"I committed too early, want to add more changes"      --soft
"I committed the wrong things, want to re-sort them"   --mixed
"This entire commit was a mistake, delete everything"   --hard

##Mistake 3: Modified a File and Want to Discard Changes

The situation: You edited a file, realized it was all wrong, and want to throw away your local edits and get the last committed version back.

1
2
3
4
5
6
7
8
9
10
11
12
13
echo "good content" > app.py
git add app.py
git commit -m "add good content"

#Now make a mess
echo "terrible mistake" > app.py
cat app.py
#terrible mistake

#Discard the edit, restore to last committed version
git restore app.py
cat app.py
#good content

Warning: git restore <file> throws away your uncommitted changes with no way to recover them. Only do this if you are sure.


##Mistake 4: Want to Edit the Last Commit Message

You just committed but the message has a typo or is unclear:

1
2
3
4
5
6
7
git commit -m "Add login funtionality"   #typo!

#Fix the message (before pushing)
git commit --amend -m "Add login functionality"

git log --oneline
#Shows the corrected message

You can also add a forgotten file to the last commit:

1
2
git add forgotten_file.py
git commit --amend --no-edit   #keep the same message, just add the file

Only use --amend on commits you have NOT pushed yet. Amending a pushed commit causes problems for teammates.


##Mistake 5: How to See What Changed (git log + git diff)

Before fixing any mistake, understand what happened first:

1
2
3
4
5
6
7
8
9
10
11
#See recent commits
git log --oneline -5

#See exactly what a specific commit changed
git show a4b5c6d

#Compare two commits
git diff a4b5c6d f1a2b3c

#See what changed in the last commit
git diff HEAD~1 HEAD

##Safety Rules

Rule Why
Commit often The more commits you have, the easier it is to pinpoint and undo a mistake
Never use --hard without checking git log first Know what you are about to delete
Never --amend or reset pushed commits It rewrites history and breaks your teammates’ clones
Add .gitignore before your first commit Secrets and logs committed once are hard to fully erase
When in doubt, git status It always tells you what state you are in

##Quick Reference

Situation Command
Unstage a file git restore --staged <file>
Unstage everything git restore --staged .
Discard file edits git restore <file>
Undo last commit, keep staged git reset --soft HEAD~1
Undo last commit, unstage too git reset --mixed HEAD~1
Undo last commit, delete changes git reset --hard HEAD~1
Fix last commit message git commit --amend -m "new message"
Add forgotten file to last commit git add file && git commit --amend --no-edit

Next: 05-remote-collaboration.md — Push your work and collaborate with a team

This post is licensed under CC BY 4.0 by the author.