Git can also reset the revision history to a specific point so that you can start over from that point.
Suppose you realise your last few commits have gone in the wrong direction, and you want to go back to an earlier commit and continue from there — as if the “bad” commits never happened. Git’s reset feature can help you do that.
Git reset moves the tip of the current branch to a specific commit, optionally adjusting your staged and unstaged changes to match. This effectively rewrites the branch's history by discarding any commits that came after that point.
Reset is different from the checkout feature:
- Reset: Lets you start over from a past state. Rewrites history by moving the branch ref.
- Checkout: Lets you explore a past state without rewriting history. Moves the
HEAD
ref.
→
[reset to C2
...]
master
branch!There are three types of resets: soft, mixed, hard. All three moves the branch pointer to a new commit but they vary based on what happens to the staging area and the working directory.
- soft reset: Moves the cumulative changes from the discarded commits in to the staging area, waiting to be committed again. Any staged and unstaged changes that existed before the reset will remain untouched.
- mixed reset: Cumulative changes from the discarded commits, and any existing staged changes, are moved into the working directory.
- hard reset: All staged and unstaged changes are discarded. Both the working directory and the staging area are aligned with the target commit (as if no changes were done after that commit).
1 First, set the stage as follows (e.g., in the things
repo):
i) Add four commits that are supposedly 'bad' commits.
ii) Do a 'bad' change to one file and stage it.
iii) Do a 'bad' change to another file, but don't stage it.
The following commands can be used to add commits B1
-B4
:
echo "bad colour" >> colours.txt
git commit -am "Incorrectly update colours.txt"
echo "bad shape" >> shapes.txt
git commit -am "Incorrectly update shapes.txt"
echo "bad fruit" >> fruits.txt
git commit -am "Incorrectly update fruits.txt"
echo "bad line" >> incorrect.txt
git add incorrect.txt
git commit -m "Add incorrect.txt"
echo "another bad colour" >> colours.txt
git add colours.txt
echo "another bad shape" >> shapes.txt
Now we have some 'bad' commits and some 'bad' changes in both the staging area and the working directory. Let's use the reset feature to get rid of all of them, but do it in three steps so that you can learn all three types of resets.
2 Do a soft reset to B2
(i.e., discard last two commits). Verify,
- the
master
branch is now pointing atB2
, and, - the changes that were in the discarded commits are now in the staging area.
Use the git reset --soft <commit>
command to do a soft reset.
git reset --soft HEAD~2
You can run the following commands to verify the current status of the repo is as expected.
git status # check overall status
git log --oneline --decorate # check the branch tip
git diff # check unstaged changes
git diff --staged # check staged changes
Right-click on the commit that you want to reset to, and choose Reset <branch-name> to this commit
option.

In the next dialog, choose Soft - keep all local changes
.

3 Do a mixed reset to commit B1
. Verify,
- the
master
branch is now pointing atB1
. - the staging area is empty.
- the accumulated changes from all three discarded commits (including those from the previous soft reset) are now appearing as unstaged changes in the working directory.
Note howincorrect.txt
appears as an 'untracked' file -- this is because unstaging a change of type 'add file' results in an untracked file.
Use the git --mixed reset <commit>
command to do a mixed reset (the --mixed
flag is the default, and can be omitted).
git reset HEAD~1
Verify the repo status, as before.
Similar to the previous reset, but choose the Mixed - keep working copy but reset index
option in the reset dialog.

4 Do a hard reset to commit C4
. Verify,
- the
master
branch is now pointing atC4
i.e., all 'bad' commits are gone. - the staging area is empty.
- there are no unstaged changes (except for the untracked files
incorrect.txt
-- Git leaves untracked files alone, as untracked files are not meant to be under Git's control).
Use the git --hard reset <commit>
command.
git reset --hard HEAD~1
Verify the repo status, as before.
Similar to the previous reset, but choose the Hard - discard all working copy changes
option.