Git Restore, Reset, and Revert: Choosing the Operation by State
Choose among git restore, git reset, and git revert by identifying which repository state must change: working tree, index, branch tip, or recorded history.
Basic
Start with the state that must change
The three commands overlap in everyday language because all three can be involved in undoing a change, but they operate on different parts of Git state. Ask one question first: what must change? If only tracked file content in the working tree must change, think `git restore`. If the branch tip itself must move to another commit, think `git reset`. If an existing commit must remain in history while its effect is recorded as a new reversal commit, think `git revert`.
Working tree only -> git restore <path>
Index only -> git restore --staged <path>
Working tree + index -> git restore --source=<tree> --staged --worktree <path>
Branch tip + local state -> git reset [--soft|--mixed|--hard] <commit>
History-preserving undo -> git revert <commit>Quick check
A tracked file has an unwanted working-tree edit, but the staged version is the version you want to keep. Which operation targets that state?
The index contains the desired version, while the working tree contains an unwanted tracked edit.The working tree matches the index and the branch tip is unchanged.
When only the index must change
If a change is staged but should no longer be staged, the target is the index. `git restore --staged <path>` restores the index entry from `HEAD` by default and leaves the working tree alone. The path form of `git reset` also updates only the index; the official reset documentation describes it as equivalent to `git restore --staged <path>`. This is an important boundary: neither operation creates a new commit or moves the branch tip in this path form.
git restore --staged notes.txt
# equivalent index-only form:
git reset HEAD -- notes.txt
git status --shortQuick check
You want to unstage `notes.txt` while keeping its working-tree edit. Which pair represents the index-only operation?
A tracked change is staged and also exists in the working tree.The index matches HEAD while the working-tree edit remains unstaged.
When both file states must match a chosen tree
Sometimes the desired source is neither the current index nor necessarily `HEAD`. `git restore --source=<tree> --staged --worktree <path>` can replace both the index entry and working-tree file with the selected tree's version. This changes local content state for the selected path; it does not move the current branch tip and does not create a commit.
git restore --source=HEAD~1 --staged --worktree app.txt
git diff --cached -- app.txt
git diff -- app.txt
git rev-parse HEADQuick check
What does `git restore --source=HEAD~1 --staged --worktree app.txt` deliberately avoid changing?
HEAD names the current commit and a prior commit contains the desired version of one tracked path.The path matches the selected source in both local states while HEAD still names the same commit.
When the branch tip must move
Commit-form `git reset <commit>` changes which commit the current branch points to. Its mode determines what happens to the index and working tree: `--soft` moves the branch tip only; `--mixed` also resets the index; `--hard` also updates tracked working-tree content to the target. The default commit-form mode is mixed. This is fundamentally different from path-form reset, which does not move HEAD.
git reset --soft HEAD~1
git rev-parse HEAD
git status --short
# or, when intentionally moving all three local states:
git reset --hard HEAD~1Quick check
Which form of `git reset` changes the current branch tip?
The branch tip must point at an earlier commit.HEAD moves to the selected commit; the chosen reset mode determines the index and working-tree effects.
When history must record the reversal
If the requirement is not to move the branch tip backward but to record that an earlier commit's effect is being undone, `git revert <commit>` is the history operation. A successful revert creates a new commit. The original target commit remains in history. Git's official documentation requires the working tree to be clean relative to `HEAD` for the normal revert operation; conflicts can put a revert sequence in progress for resolution and continuation.
git revert HEAD
git log --oneline --decorate -3
git rev-parse HEAD^
git rev-parse HEAD^^Quick check
A shared branch must retain the original commit while recording its reversal as a new commit. Which operation matches that requirement?
The original commit must remain reachable and its effect must be reversed in recorded history.A new revert commit is added after the existing history.
Similar content, different history
Two commands can sometimes leave a file looking the same while producing different repository histories. For example, restoring a path from an older tree changes selected local content but leaves the branch tip where it was. A hard reset to that commit moves the branch tip and updates local state. A revert of a later commit creates another commit. The visible file contents alone are therefore not enough to identify the correct operation; inspect `HEAD`, the index, and the working tree separately.
git rev-parse HEAD
git status --short
git diff --cached
git diff
git log --oneline --decorate --graph -5Quick check
Why can checking only the final file contents lead to the wrong choice among restore, reset, and revert?
The file appears correct after an operation.You also verify HEAD, index, working tree, and history before deciding that the operation had the intended effect.
Decision lab: predict before you execute
For each scenario, name the state that must change before choosing a command. Then execute it in a disposable repository and verify the predicted state. Do not decide from the word 'undo' alone. A reliable analysis records at least the target `HEAD`, index state, working-tree state, and whether the commit graph should gain, lose, or retain a commit at the branch tip.
# Observe before and after each decision
git rev-parse HEAD
git status --short
git diff --cached
git diff
git log --oneline --decorate --graph -5Quick check
What is the first question in this decision lab?
You are given a repository state and a desired end state.You identify the state transition before selecting the Git command.
Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Official-source boundary
This synthesis is based only on the official Git documentation for `git restore`, `git reset`, and `git revert`, plus the official Git user manual's reset/restore/revert comparison. It deliberately does not introduce reflog recovery, branch management, rebase, cherry-pick, or merge workflows. The local verification executable is Git 2.47.3; the current official documentation baseline is Git 2.56.0.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.