Git and GitHub course menu
git reset Soft, Mixed and Hard, and Recovering with git reflog
Understand git reset --soft, --mixed and --hard, undo commits, move work off main, and recover lost commits and deleted branches with git reflog.
On this page
git reset moves the current branch to another commit. The commits after that point are no longer on the branch. What happens to their changes depends on the mode.
The three modes#
Each mode goes one step further:
Start from three commits:
git log --onelinebf1c290 Commit three
f5af04c Commit two
83befe6 Commit one--soft: undo the commit, keep it staged#
git reset --soft HEAD~1
git log --oneline
git status --shortf5af04c Commit two
83befe6 Commit one
M app.txtThe commit is gone, but its changes are staged, ready to commit again. Use this to rewrite the last commit, or to combine commits.
--mixed: undo the commit, keep the edits#
git reset HEAD~1
git status --shortUnstaged changes after reset:
M app.txt
M app.txtThe changes are back in your files but unstaged. Use this to reorganise work into different commits.
--hard: throw it all away#
git reset --hard HEAD~1
git log --oneline
cat app.txtHEAD is now at f5af04c Commit two
f5af04c Commit two
83befe6 Commit one
one
twoThe branch, staging area and files all went back.
The reflog: your safety net#
Commit three has gone from the log, but it is not deleted. Git records every position HEAD has been at, in a local log called the reflog:
git reflog -n 4f5af04c HEAD@{0}: reset: moving to HEAD~1
c2ab56f HEAD@{1}: commit: Commit three
f5af04c HEAD@{2}: reset: moving to HEAD~1
db63e10 HEAD@{3}: commit: Commit threeHEAD@{1} means "where HEAD was one move ago". Go back there:
git reset --hard HEAD@{1}
git log --onelineHEAD is now at c2ab56f Commit three
c2ab56f Commit three
f5af04c Commit two
83befe6 Commit oneThe "lost" commit has returned. This works after a bad reset, rebase or amend.
Recover a deleted branch#
git switch -q -c experiment
echo "idea" > idea.txt
git add .
git commit -q -m "Try an idea"
git switch -q main
git branch -D experimentDeleted branch experiment (was d004a4f).The output shows the ID of the last commit. If you have lost that too, find it in the reflog. Here, HEAD@{1} is the position just before we switched back to main:
git branch experiment HEAD@{1}
git log --oneline experiment -n 1d004a4f Try an ideaHow long does the reflog last?#
The reflog is local: it is not pushed, and a fresh clone has none. Entries last 90 days by default, or 30 days for commits no longer on any branch, and after that Git may delete them. Unsaved edits were never committed, so they are never in the reflog.
Fix: commits made on main by mistake#
You should have been on a feature branch. Create the branch where you are, then move main back. Here the last commit belongs on the new branch:
git switch -q -c feature
git switch -q main
git reset --hard HEAD~1
git log --oneline --graph --allHEAD is now at f5af04c Commit two
* d004a4f Try an idea
* c2ab56f Commit three
* f5af04c Commit two
* 83befe6 Commit oneIf you had already pushed to main, don't do this: use git revert.
Unstage with reset#
You may see git reset HEAD file in older guides. It does the same as git restore --staged file.
Common mistakes#
Practice#
Practice exercise
On feature, remove the last commit with git reset --hard, confirm it has gone, then bring it back using the reflog and print the log.
Show solution
git switch -q feature
git reset -q --hard HEAD~1
git log --oneline -n 1
git reset -q --hard HEAD@{1}
git log --oneline -n 1f5af04c Commit two
c2ab56f Commit threeKey takeaway#
Finished this lesson?