In this example, we'll learn how we can undo a commit as if it had never happened. We'll learn how we can use the reset
command to effectively discard the commit and thereby reset our branch to the desired state.
In this example, we'll use the example of the hello world
repository, clone the repository, and change your working directory to the cloned one:
$ git clone https://github.com/dvaske/hello_world_cookbook.git $ cd hello_world_cookbook
First, we'll try to undo the latest commit in the repository as though it never happened:
$ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean
$ ls HelloWorld.java Makefile hello_world.c
--oneline
switch to limit the output:$ git log --oneline 3061dc6 Adds Java version of 'hello world' 9c7532f Fixes compiler warnings 5b5d692 Initial commit, K&R hello world
3061dc6 Adds Java version of 'hello world'
commit. We will now undo the commit as though it never happened and the history won't show it:$ git reset --hard HEAD^ HEAD is now at 9c7532f Fixes compiler warnings
$ git log --oneline 9c7532f Fixes compiler warnings 5b5d692 Initial commit, K&R hello world $ git status On branch master Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) nothing to commit, working directory clean $ ls hello_world.c
Makefile
and HelloWorld.java
).In the last output of git status
, you can see that our master
branch is one behind origin/master
. This is similar to what we mentioned at the beginning of the chapter because we are removing and undoing commits that are already published. Also, as mentioned, you should only perform the undo and redo (git reset
) operations on commits that are not shared yet. Here, we only show it on the published commits to make the example easy to reproduce.
Effectively, we are just changing the pointer of the master
branch to point to the previous commit HEAD, which means the first parent of HEAD. Now the branch will point to 9c7532f
, instead of the commit we removed, 35b29ae
. This is shown in the following figure:
The figure also shows that the original 3061dc6
commit is still present in the repository, but new commits on the master
branch will start from 9c7532f
; the 3061dc6
commit is called a
dangling commit.
When the reset
command is executed, Git looks at the commit pointed to by HEAD
and finds the parent commit from this. The current branch, master
, and the HEAD
pointer are then reset to the parent commit and so are the staging area and working tree.