Git Reset: Moving HEAD and Controlling Local State
Use git reset precisely by separating its path form from commit form and proving the effects of soft, mixed, and hard reset on HEAD, the index, and the working tree.
Basic
What git reset changes
`git reset` has two distinct forms that must not be conflated. With paths, it updates selected index entries and leaves the working tree and current branch tip alone. With a commit and a reset mode, it moves the current branch tip (`HEAD`) to that commit and, depending on the mode, may also update the index and working tree.
git reset HEAD -- path/to/file
git reset --mixed HEAD~1
git reset --soft HEAD~1
git reset --hard HEAD~1Quick check
What does the path form `git reset HEAD -- file.txt` primarily change?
A staged change exists for file.txt.The index is restored to HEAD for file.txt; the working-tree edit remains.
Path reset: unstage without discarding the working-tree edit
The path form is the precise operation for removing selected paths from the index while keeping their working-tree contents. It is therefore useful when a file was staged accidentally and you want the working copy to remain editable. This overlaps with `git restore --staged`, but the curriculum keeps the commands distinct so learners can recognize both the historical path form of reset and the newer restore interface.
git add file.txt
git reset HEAD -- file.txt
git status --shortQuick check
After `git reset HEAD -- file.txt`, what happens to an already-edited working-tree file?
file.txt contains a local edit and is staged.file.txt remains edited but is no longer staged.
Commit reset modes move the branch tip
When a commit is supplied in the commit form, reset moves the current branch tip to that commit. Git also records the previous tip in `ORIG_HEAD` before the operation. The mode determines what happens to the index and working tree after the branch tip moves.
git reset --soft HEAD~1
git rev-parse HEAD
git rev-parse ORIG_HEADQuick check
What is the defining reference change made by `git reset --soft HEAD~1`?
HEAD points to the newest commit.The branch points to its parent and ORIG_HEAD records the previous tip.
Soft reset: move HEAD, keep local content staged
`--soft` changes only the branch tip among the three primary locations discussed here. The index and working tree are left unchanged. If the removed commit contained changes, those changes therefore remain staged relative to the new `HEAD`.
git reset --soft HEAD~1
git diff --cached
git status --shortQuick check
After a soft reset to the parent, where do changes from the removed commit remain?
A commit is the current HEAD.HEAD moves to its parent while the former commit changes remain staged.
Mixed reset: move HEAD and reset the index
`--mixed` is the default reset mode. It moves the current branch tip and makes the index match the new `HEAD`, while leaving the working tree unchanged. This commonly turns changes that were committed by the removed tip into ordinary unstaged working-tree changes.
git reset --mixed HEAD~1
git diff --cached
git diffQuick check
What does the default `git reset HEAD~1` do to the index?
HEAD points to the newest commit.HEAD moves to its parent and the index matches that parent.
Hard reset: update all three local states
`--hard` moves the branch tip, resets the index to the target, and updates the working tree to match the target. It can discard local tracked changes and can remove tracked paths that do not exist in the target. Git also documents that untracked files or directories can be removed when they obstruct paths being written. Treat `--hard` as destructive and use a disposable repository while learning it.
git reset --hard HEAD~1
git status --short
git rev-parse HEADQuick check
Which local states does `git reset --hard HEAD~1` align with the target commit?
HEAD, index, and working tree differ from the target.All three local states match the target commit.
Reset does not create a replacement commit
A commit-form reset changes which commit the current branch points to; it does not create a new commit that reverses the old one. The old tip can still be named through `ORIG_HEAD` immediately after the reset, and the underlying commit object is not rewritten by the reset itself. Creating a new reversing commit is the separate responsibility of `git revert`, which belongs to its own lesson.
git reset --soft HEAD~1
git rev-parse HEAD
git rev-parse ORIG_HEAD
git rev-list --count HEADQuick check
Which statement accurately distinguishes reset from revert?
A branch points to a commit containing a change.Reset can point the branch elsewhere without creating a reversing commit.
Reset is not a substitute for restore
`git restore` was established in the previous lesson as the command for correcting selected working-tree and/or index content without moving the branch tip. `git reset` adds a distinct reference-moving form when a commit is supplied. The path form can overlap with `git restore --staged`; choose the command according to the state transition you intend, not by treating their names as synonyms.
git restore --staged -- file.txt
git reset HEAD -- file.txtQuick check
Which operation actually moves the current branch tip?
HEAD points to commit B.After `git reset --mixed HEAD~1`, the branch points to commit A.
Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Official-source boundary
This lesson is based on the official Git documentation for `git reset` and the official Git revision syntax used for reset targets. It deliberately postpones `git revert`, reflogs, recovery of abandoned commits, and advanced reset modes such as `--merge` and `--keep` until their own curriculum ownership or a later advanced lesson. 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.