A Detailed Explanation of Git Reset and Undo Operations
Reset is a powerful undo command in Git. With Reset, you can undo commits, unstage changes, and discard modifications. Understanding the three modes of Reset is crucial for version control.
1. Revisiting Basic Concepts
(1) What Is a Reset?
A reset is an operation that moves the current branch to a specified location:
- Move Branch Pointer: Move HEAD and the branch pointer to the specified commit
- Update the temporary storage area: Determine whether to update the temporary storage area based on the mode
- Update Workspace: Determine whether to update the workspace based on the mode
- Undo Actions: Undo commit, staging, and modifications
graph TB
A[git reset] --> B{Pattern}
B -->|soft| C[Move only the pointer<br/>Preserve the temporary storage area and the workspace]
B -->|mixed| D[Move the pointer+Update the temporary storage area<br/>Save Workspace]
B -->|hard| E[Move the pointer+Update the temporary storage area+Update Workspace]
style C fill:#d4edda
style D fill:#fff3cd
style E fill:#f8d7da
(2) The Three Areas of Git
To understand reset, you first need to understand Git's three working areas:
graph TB
HEAD[HEADPointer] --> Branch[Branch pointer]
Branch --> Repo[Repository<br/>Repository]
Repo --> Stage[Buffer<br/>Staging Area]
Stage --> Work[Workspace<br/>Working Directory]
style HEAD fill:#f8d7da
style Repo fill:#c3e6cb
style Stage fill:#d4edda
style Work fill:#fff3cd
- HEAD: Points to the current branch
- Branch pointer: Points to a specific commit
- Repository: Stores all commits
- Staging Area: Changes ready to be committed
- Workspace: The files you are actually editing
(3) Reset Direction
You can reset forward or backward:
- Reset Backward: Undo the commit and revert to the previous state
- Reset Forward: Move forward to the next commit (rarely used)
2. Three Reset Modes
(1) Soft reset (--soft)
Move only the HEAD and branch pointers, while preserving the staging area and working area.
▶ Example: Soft Reset
# View Current Status
git log --oneline -3
# Output:
# d4e5f6g (HEAD -> main) feat: Add FeatureC
# h7i8j9k feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# Soft reset to the previous commit
git reset --soft HEAD~1
# View Status
git status
# Output:
# On branch main
# Changes to be committed:
# (use "git restore --staged <file>..." to unstage)
# new file: feature-c.js
# View History
git log --oneline -3
# Output:
# h7i8j9k (HEAD -> main) feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# a1b2c3d Initial commit
# The commit is still in the staging area,You can resubmit it.
git commit -m "feat: Re-add FeatureC"
Effects of a soft reset:
- ✅ Revert commit
- ✅ Keep changes in the staging area (changes are still in the staging area)
- ✅ Keep the workspace (files remain unchanged)
(2) Mixed reset (--mixed, default)
Move the HEAD and branch pointers, update the staging area, and preserve the working directory.
▶ Example: Hybrid Reset
# View Current Status
git log --oneline -3
# Output:
# d4e5f6g (HEAD -> main) feat: Add FeatureC
# h7i8j9k feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# Mixed Reset(Default Mode)
git reset HEAD~1
# Or specify explicitly
git reset --mixed HEAD~1
# View Status
git status
# Output:
# On branch main
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# feature-c.js
# View History
git log --oneline -3
# Output:
# h7i8j9k (HEAD -> main) feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# Edits in the workspace,Needs to be redoneadd
git add feature-c.js
git commit -m "feat: Re-add FeatureC"
Effects of a hybrid reset:
- ✅ Revert commit
- ✅ Unstage (move changes from the staging area to the working area)
- ✅ Preserve workspace (files remain unchanged)
(3) Hard reset (--hard)
Move the HEAD and branch pointers, and update the staging area and working directory.
▶ Example: Hard Reset
# View Current Status
git log --oneline -3
# Output:
# d4e5f6g (HEAD -> main) feat: Add FeatureC
# h7i8j9k feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# Hard Reset
git reset --hard HEAD~1
# Output:
# HEAD is now at h7i8j9k feat: Add FeatureB
# View Status
git status
# Output:
# On branch main
# nothing to commit, working tree clean
# View History
git log --oneline -3
# Output:
# h7i8j9k (HEAD -> main) feat: Add FeatureB
# k9l0m1n feat: Add FeatureA
# ⚠️ FeaturesCThe changes have been completely lost!
Effects of a hard reset:
- ✅ Revert commit
- ✅ Unstash
- ✅ Discard workspace changes (restore the file to the state of a specified commit)
⚠️ Warning: A hard reset will cause all unsaved changes to be lost. Use with caution!
3. Comparison of Reset Modes
(1) Comparison Table of the Three Modes
| Mode | HEAD | Staging Area | Working Directory | Purpose |
|---|---|---|---|---|
| soft | Move | Unchangeable | Unchangeable | Undo commit, recommit |
| mixed | Move | Update | Keep | Revert and Stage |
| hard | Move | Update | Update | Fully undo, discard changes |
(2) Illustrations of the Three Modes
graph TB
subgraph Before the reset
A1[HEAD -> C3] --> B1[Buffer: C3Status]
B1 --> C1[Workspace: C3Status]
end
subgraph softReset
A2[HEAD -> C2] --> B2[Buffer: C3Status<br/>Retain]
B2 --> C2[Workspace: C3Status<br/>Retain]
end
subgraph mixedReset
A3[HEAD -> C2] --> B3[Buffer: C2Status<br/>Update]
B3 --> C3[Workspace: C3Status<br/>Retain]
end
subgraph hardReset
A4[HEAD -> C2] --> B4[Buffer: C2Status<br/>Update]
B4 --> C4[Workspace: C2Status<br/>Update]
end
(3) Select the appropriate mode
Scenarios for using soft:
- I made a mistake in the information I submitted and would like to resubmit it
- I want to merge multiple commits into one
- Edit the content of the submission
Scenarios for using mixed:
- Revert the commit and reorganize the changes
- Uncheck the files in the staging area and reselect the files you want to commit
- Default mode, most commonly used
Scenarios for using "hard":
- Discard all current changes
- Return to a specific state
- Clean up the workspace (use with caution)
4. Detailed Explanation of the Reset Process
(1) Reset to a specific commit
▶ Example: Revert to a specific commit
# Revert to a Specific CommitID
git reset a1b2c3d
# Reset to a Specific Tag
git reset v1.0.0
# Reset to Relative Position
git reset HEAD~1 # Previous Commit
git reset HEAD~3 # Previous 3 commits
git reset HEAD^ # Previous Commit(Equivalent toHEAD~1)
git reset HEAD^^ # The first two commits
# Reset to a remote branch
git reset origin/main
(2) Undo Stash
▶ Example: Unstaging
# View the Stash
git status
# Output:
# Changes to be committed:
# new file: file1.js
# new file: file2.js
# Uncheck "Save a file to the clipboard"
git reset file1.js
# Or userestore
git restore --staged file1.js
# Discard all changes
git reset
# View Status
git status
# Output:
# Untracked files:
# file1.js
# file2.js
(3) Undo changes to the workspace
▶ Example: Discarding workspace changes
# View Workspace Changes
git status
# Output:
# Changes not staged for commit:
# modified: README.md
# Discard Workspace Changes
git restore README.md
# Or use the old syntax
git checkout -- README.md
# Discard all workspace changes
git restore .
# Or
git checkout -- .
# ⚠️ This will permanently lose any unsaved changes.!
5. The Difference Between "Reset" and "Revert"
(1) reset vs revert
| Feature | reset | revert |
|---|---|---|
| How to Use | Move the pointer | Create a new commit |
| History | Delete History | Keep History |
| Pushed | Requires forced push | Can be pushed normally |
| Safety | Commits may be lost | Commits will not be lost |
| Use Cases | Unpushed local commits | Pushed commits |
(2) Use reset to undo a local commit
▶ Example: Use reset to undo a local commit
# An incorrect commit was created locally
git commit -m "Incorrect Submission"
# Undo Commit(Keep the changes)
git reset --soft HEAD~1
# Resubmit after making corrections
git commit -m "Correct Submission"
# Regular Push Notifications
git push origin main
(3) Use revert to undo a pushed commit
▶ Example: Use revert to undo a pushed commit
# Pushed commits
git push origin main
# UsagerevertCreate a Revert Commit
git revert a1b2c3d
# Output:
# [main d4e5f6g] Revert "Incorrect Submission"
# 1 file changed, 1 deletion(-)
# Regular Push Notifications
git push origin main
# The history will retain the original submission andrevertSubmit
git log --oneline
# Output:
# d4e5f6g Revert "Incorrect Submission"
# a1b2c3d Incorrect Submission
# h7i8j9k Normal submission
6. Best Practices for Resetting
(1) Security Reset Process
▶ Example: Security Reset
# 1. View Current Status
git status
git log --oneline -5
# 2. Confirm which commit to roll back to
git log --oneline
# 3. First, create a backup branch(Optional)
git branch backup-branch
# 4. Perform a reset
git reset --hard a1b2c3d
# 5. Verification Results
git log --oneline -5
git status
# If the reset is done incorrectly,Can be restored
git reset --hard backup-branch
(2) Recovery Using reflog
▶ Example: Recovering from an incorrect reset
# Operational error:A hard reset caused the commit to be lost
git reset --hard HEAD~3
# Viewreflog
git reflog
# Output:
# a1b2c3d HEAD@{0}: reset: moving to HEAD~3
# d4e5f6g HEAD@{1}: commit: feat: Add FeatureC
# h7i8j9k HEAD@{2}: commit: feat: Add FeatureB
# k9l0m1n HEAD@{3}: commit: feat: Add FeatureA
# Restore to the state prior to the reset
git reset --hard d4e5f6g
# Verification and Recovery
git log --oneline -5
(3) Reset the workflow
graph TB
A[The operation needs to be undone] --> B{Has the operation been pushed??}
B -->|Not pushed| C[Usagereset]
B -->|Pushed| D[Usagerevert]
C --> E{Keep or Discard Changes??}
E -->|Yes| F[reset --soft/--mixed]
E -->|No| G[reset --hard]
D --> H[Create a Revert Commit]
style C fill:#d4edda
style D fill:#fff3cd
style G fill:#f8d7da
❓ FAQ
reset, and when should I use revert?reset to undo them; for commits that have been pushed, use revert to create a reverse commit. reset rewrites history, while revert preserves it.reset --hard cause data loss?git add operation?git reset <file> or git restore --staged <file> to discard a staging. Use git reset to discard all staging.git reflog to view the operation history, locate the HEAD position before the reset, and use git reset --hard <commit> to restore it. Alternatively, if you have a backup branch, simply reset to that branch.📖 Summary
- A reset is an operation that moves the branch pointer to a specified location.
- Three modes: soft (preserves changes), mixed (preserves the workspace), and hard (complete reset)
- Soft reset: Revert the commit while preserving the staging area and working directory
- Mixed reset: Revert commits and staging, but keep the working directory (default)
- Hard reset: Completely undo all changes (use with caution)
- reset vs. revert: "reset" is used for local branches, while "revert" is used for branches that have been pushed
📝 Exercises
-
Basic Exercise: Create multiple commits, reset them using each of the three reset modes, observe the changes in the staging area and working directory, and understand the differences between the three modes.
-
Advanced Exercise: Simulate an incorrect commit scenario: Create an incorrect commit, use
resetto undo it, and then commit the correct version to experience the practical application ofreset. -
Challenge: Experience the power of reflog: Perform multiple reset operations, use reflog to view the history of operations, recover from a failed reset, and understand Git’s data safety mechanisms.



