Learning objectives
By the end of this module, you should be able to:
- Distinguish restore, reset and revert.
- Recover local reference movement with reflog.
- Use stash deliberately for temporary work-in-progress.
Undo commands change different layers
git restore changes working-tree and/or index content. git reset moves a branch reference and can also affect the index/working tree depending on mode. git revert creates a new commit that inverses an earlier commit, making it suitable for shared history.
Reflog is a local safety trail
Reflogs record recent updates to local references such as HEAD. They can help locate commits after an accidental reset or branch move, subject to repository retention and garbage collection. Reflog is local and is not a substitute for backups.
Stash is temporary, not archival
git stash can park tracked work (and optionally untracked files) while you switch context. Name stashes when useful and apply/pop carefully if conflicts are possible.
Worked examples
See the idea in practice.
Compare safe recovery tools
git restore app.txt
git restore --staged app.txt
git revert <commit>
git reflog --oneline | head
- restore can discard uncommitted file edits, so inspect first.
- revert preserves shared history by adding a new commit.
- reflog helps find recent local reference positions.
Hands-on lab
Lab — Recover from a mistaken local reset
Goal: Create commits, move main backward, then recover the lost tip using reflog.
Before you start
- Git 2.23 or newer is recommended so the labs can use git switch and git restore.
- Run labs in a disposable working directory; the included validator creates and removes its own temporary repository.
STEP 1Create three commits
mkdir -p ~/gnu-git-labs/module11 && cd ~/gnu-git-labs/module11
git init -b main
git config user.name "GNU Learner"
git config user.email "learner@example.invalid"
printf "one\n" > data.txt
git add data.txt && git commit -m "Add one"
printf "two\n" >> data.txt && git commit -am "Add two"
printf "three\n" >> data.txt && git commit -am "Add three"
STEP 2Record the current tip
git rev-parse HEAD > /tmp/gnu-git-module11-tip
STEP 3Move main backward intentionally
git reset --hard HEAD~1
cat data.txt
STEP 4Inspect reflog and recover
git reflog --oneline -5
git reset --hard "$(cat /tmp/gnu-git-module11-tip)"
cat data.txt
STEP 5Clean helper file
rm -f /tmp/gnu-git-module11-tip
Verify
- After the first reset, line three disappears.
- After recovery, line three returns and HEAD matches the recorded commit.
Expected outcome
- Learners see why reflog can recover recent local reference mistakes.
If it fails
- Never run reset --hard on valuable uncommitted work without a backup or clear intent.
- On shared published history, prefer revert unless the team explicitly coordinates history rewriting.
Real-world connectionProduction support frequently requires undoing a bad change while preserving an auditable history; revert is usually safer for shared branches.
Avoid these traps
Common mistakes
- Using reset --hard as a generic cleanup command.
- Rewriting a shared branch without coordination.
- Treating stash or reflog as permanent backup storage.
Knowledge check
Can you explain it without looking back?
Open each answer only after you have tried to answer the question yourself.
1Which command creates a new commit that reverses an earlier commit?
git revert.
2What does git reset primarily move?
A branch/reference tip, with optional index/working-tree effects depending on mode.
3What can git reflog help recover?
Recent local reference positions, such as a commit before an accidental reset.