Git & Command Line Tutorial · Git Basics · Lesson 11 of 20
Undoing Changes
Undo safely at every stage: discard edits with git restore, unstage, amend the last commit, revert a commit, and reset when you really mean it.
Which undo?
| Situation | Command |
|---|---|
| Discard edits to a file (not staged) | git restore file |
| Unstage a file (keep the edits) | git restore --staged file |
| Fix the last commit's message or add a forgotten file | git commit --amend |
| Undo a commit that's already pushed/shared | git revert <commit> (adds a new commit that reverses it) |
| Throw away local commits | git reset --hard <commit> (destructive!) |
| Undo commits but keep the changes | git reset --soft HEAD~1 |
Golden rule: don't rewrite commits other people already have (amend, reset, rebase on pushed branches). Use revert for shared history.
git restore and git switch (since Git 2.23) replace the many jobs of the older git checkout.
git init -b main --quiet app && cd app
echo "v1" > config.txt && git add . && git commit -m "Add config" --quiet
echo "oops, broken" > config.txt
git restore config.txt # discard the edit
echo "after restore: $(cat config.txt)"
echo "v2" > config.txt && git add config.txt
git restore --staged config.txt # unstage, keep the edit
git status --short
git commit -am "Updte config" --quiet
git commit --amend -m "Update config" --quiet # fix the typo in the last message
git log --oneline
echo "bad idea" > config.txt && git commit -am "Bad change" --quiet
git revert HEAD --no-edit > /dev/null # a new commit that undoes it
echo "after revert: $(cat config.txt)"
git log --oneline
git reset --hard HEAD~2 --quiet # drop the last two commits entirely (local only!)
git log --oneline
Output
after restore: v1 M config.txt 3d52a50 Update config dc1920b Add config after revert: v2 38578d7 Revert "Bad change" ce38963 Bad change 3d52a50 Update config dc1920b Add config 3d52a50 Update config dc1920b Add config
Run this on your computer — see “Get Started” for setup.
Test yourself
A bad commit was already pushed to a shared branch. How should you undo it?
git reset --hardgit revert <commit>git commit --amendDelete the repository
Show answer
Answer: git revert <commit>