Introduction to git undo commit
Git has provided a variety of functions to manage your working repository including git undo commits that are unwanted. They include git checkout, git clean, git revert, and git reset among others. This enables you to continue with your work safely while removing commits that you find unhelpful for the project.
Git environment provides diversity in managing different sections of a project in form of branches or repositories. Any data committed in the cause of production is recorded and can be traced back in time or undone. That is made possible by git undo commit
operation enabled by the above-mentioned functions. Undoing facilitates revision and correction of the history of the project commits with inconsistencies or issues.
In this tutorial, we are going to learn about git undo commit
, to undo a commit using git reset
, git revert
and accessing commits using git log
.
Lab Environment
To use and practice working with git, the first step is setting up a local working environment. I will create a remote project git_query
in my Github account and cloned it to my local workstation for this exercise. See the output below:
$ git clone https://github.com/Maureen-Mulombi/git-query.git
Sample Output:
I will be using windows 10 pro and git version 2.32.0.windows.2 throughout this demonstration of this tutorial.
Git undo commit workflow
Git has several commands to facilitate git undo commit
that you should understand to manage changes within your current repository. They include git reset
, git soft reset
, git mixed reset
and git hard reset
.
Git reset removes a staged file in the index without modifying the active directory. This process will not override any changes upon unstaging the specified file. Let’s first break down the git environment in which the reset function operates (git tree) in this section.
The git tree is made up of three basic parts:
- Working directory: manages the project files
- Staging area: stores the pre-commits
- Repository: keeps data for the past changes or commits
See the diagram below that illustrates how the git tree works:
git reset vs git reset --soft vs git reset --hard vs git reset --mixed
- git reset servers to redirect files at different cycles of the git tree. It unstages the latest commit and sets back the active tree to the second last commit.
- git reset --soft option does not change the files already in the index or active directory. It operates contrary to the git add command. It simply pushes or stages files to the index in the active repo.
- git reset --hard option behaves completely different from the git soft reset and git mixed rest when used to undo a commit. Git hard reset removes all the stored files in the index and directory of the active repository. Only use git hard rest if you want to permanently undo a commit.
- git reset --mixed command can undo a commit while maintaining the active directory history but not the index.
The above diagram is a simplified illustration of how git soft reset, git mixed reset and git hard reset operate in an active tree.
- Soft reset: affects the head and doesn’t cause changes to the index and directory
- Mixed reset: affects the head and the index but no change to the directory
- Hard reset: changes the entire tree history i.e. head, index and directory
Different Methods to perform git undo commit
In this section we will cover different examples to perform undo commit in git.
Method-1: git undo commit using soft reset
To undo a commit to latest commit from your active repository use git reset --soft HEAD~1
command. Using the HEAD option in the git soft reset command enables you to specify which commit to change.
Git uses the following syntax to facilitate git undo commit
using git soft reset command;
$ git reset --soft HEAD~1
~
sign with HEAD to define the number of times to go backward in the commit history. HEAD~1
implies that git will remove your last commit in the branch history. You may use HEAD~3
to go back to the third last commit. But in such case you could just provide the commit id if this is confusing for you. You can read more about these signs at What's the difference between HEAD^ and HEAD~ in Git?
We will use an example to demonstrate how to use git soft reset
as follows. First, let’s create a new branch jira
in the current local repo git-query
using git checkout
command.
$ git checkout -b jira
Switched to a new branch 'jira'
After committing a few changes in the jira
branch, next we will use the git log --online
command to view all the commits as shown below:
$ git log --oneline 227e05b (HEAD -> jira) q-two file 5dc53a4 q-one file 29d8e9c (origin/master, origin/HEAD, master) Initial commit
To illustrate how to undo a commit using git soft reset
command, let’s try and undo the last commit 227e05b
in our current branch which can be referred using HEAD~1
.
$ git reset --soft HEAD~1
Next check the status, you can see that the files from our commit id 227e05b
are not removed and is added to our local repo with pending changes to be committed:
$ git status
On branch jira
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: q-two.txt
We will then run git log --oneline
command to confirm the removal of the last commit 227e05b
.
$ git log --oneline 5dc53a4 (HEAD -> jira) q-one file 29d8e9c (origin/master, origin/HEAD, master) Initial commit
The results are now showing only two commits instead of three like it was before the soft reset.
Method-2: git undo commit using hard reset
Git employs the following syntax for git hard reset
command to undo a commit in the active repo;
$ git reset --hard HEAD~1
Just like the git soft reset
option, git hard reset
also utilizes the HEAD in its formula to identify the target commit to remove.
We will experiment on how to undo a commit in git using git hard reset head
command using the following example. Let’s first create a new branch test-b
in the local repository git-query
using git checkout –b
command as follows;
$ git checkout -b test-b
Switched to a new branch 'test-b'
To demonstrate how to undo a commit
using git hard reset
command we shall use the following example.
After committing a new file myfile.css
, we want to undo the commit as we will not need the file anymore for this part of the production.
First, let’s run git log --oneline
command to get the commit of the mistakenly committed file myfile.css
.
a4be714 (HEAD -> test-b) myfile.css 5dc53a4 (origin/jira, jira) q-one file 29d8e9c (origin/master, origin/HEAD, master) Initial commit
Next, we will use the git reset --hard HEAD~1
command to undo the changes permanently as shown:
$ git reset --hard HEAD~1
HEAD is now at 5dc53a4 q-one file
The head is now pointing at the second last commit unlike before. Now, we shall run the git status
command to view the current status of the active branch.
$ git status
On branch test-b
nothing to commit, working tree clean
Notice that the entire history has been cleared. There are no commits for test-b
branch.
Why git hard reset is potentially dangerous?
Git reset hard head could be a dangerous way to work with to run git undoing a commit
. Would you lose your directory history? Let’s use an example to find out.
For example we have following commit-tree A <- B <- C <-D <- E <- HEAD. Now if we want to reset to commit id B, then what would happen? Will you lose my changes done as part of C, D and E?
See the illustration below:
The answer is yes, you will lose your changes C, D and E especially if you dint commit or stage them before running the git hard reset head
.
Git hard reset head is dangerous because it never gives prompts in situations where there are unstaged or uncommitted files in the active directory. Neither will it warn you that your files are going to be overwritten which makes it easy to lose data history. Always observe caution when adopting git hard reset
function to carry out git undo a commit
.
Method-3: Perform git undo commit using mixed reset
git mixed reset
command also incorporates the HEAD option to identify which commit should be removed.
Let’s use an example to illustrate how this process takes place in a git environment. We will again use the jira
branch in our current project to illustrate how to undo commit using the git reset --mixed HEAD~1
command as follows;
First, we’ll checkout jira
branch to ensure that we are using the right branch:
$ git checkout jira
Switched to branch 'jira'
Your branch is up to date with 'origin/jira'.
Next, we will run git log --oneline
command to view all the commits.
$ git log --oneline 4ff5861 (HEAD -> jira) test-two 5dc53a4 (origin/jira, test-b) q-one file 29d8e9c (origin/master, origin/HEAD, master) Initial commit
Next, we shall now run the  git reset --mixed HEAD~1
command to undo the last commit as shown here;
$ git reset --mixed HEAD~1
Next check the status:
$ git status
On branch jira
Your branch is behind 'origin/jira' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
Untracked files:
(use "git add <file>..." to include in what will be committed)
test-two.js
nothing added to commit but untracked files present (use "git add" to track)
From the results, we have been able to undo a commit but kept the file history within the directory as untracked. Therefore, you can always go back to the file when you need it in the future.
Method-4: git undo a commit using git revert function
You can use git revert function to undo a commit in your tree history without changing the history. That’s because git revert
command doesn’t remove the old commit but rather creates a new revert commit ahead of the branch. Also when working to undo changes using git revert, you do not need to specify the head number like in git soft reset or git hard reset. The reason is that a revert operation doesn’t create a new head. It only deals with the specified commit.
We will use the following example to demonstrate how git rever
t command makes changes to a commit;
Let’s create a new branch  mybranch
 in the git-query
repo.
$ git checkout -b mybranch
Switched to a new branch 'mybranch'
We will add a file myfile.css
and commit it as shown below;
$ touch myfile.css
$ git add .
$ git commit -m "myfile"
[mybranch 689e317] myfile
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 myfile.css
Let’s now run git log –oneline
command to see the latest commit 689e317
in mybranch
$ git log --oneline 689e317 (HEAD -> mybranch) myfile 47f6da2 (jira) Merge branch 'jira' of https://github.com/Maureen-Mulombi/git-query into jira 424f81d newfile 4ff5861 (origin/jira) test-two 5dc53a4 (test-b) q-one file 29d8e9c (origin/master, origin/HEAD, master) Initial commit
We shall now run git revert head
so as to undo the last commit 689e317
as illustrated below;
$ git revert head
Revert "myfile"
This reverts commit 689e31768895acce3d392772d92d6a20ab1b977f.
On branch mybranch
Changes to be committed:
deleted: myfile.css
Now, we’ll run git status
command to view the deleted file.
$ git status
On branch mybranch
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: myfile.css
Method-5: Perform git undo commit using git --amend
You can undo a commit using git commit --amend
command as illustrated below. First, we will checkout a new branch example-1
for this experiment as follows;
$ git checkout -b example-1
Switched to a new branch 'example-1'
After committing a couple of files in the example-1
branch, we realize that the last file we committed was wrong and needs to be amended. git commit --amend
command will help to sort this out as follows. First, we will run git log
command to view the last commit as follows;
$ git log --oneline cf55725 (HEAD -> example-1) newfile 373d3af gitfile-1 added 29d8e9c (origin/master, origin/HEAD, master) Initial commit
Now let’s run git --amend –m
command to change the file name of the last commit
$ git commit --amend -m "amended file"
[example-1 6637c14] amended file
Date: Fri Aug 20 10:47:43 2021 +0300
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 gitfile-2.css
We shall now run the git log –oneline
command to see the new commit changed from newfile
to amended file
with a new commit id 6637c14
as shown below:
$ git log --oneline 6637c14 (HEAD -> example-1) amended file 373d3af gitfile-1 added 29d8e9c (origin/master, origin/HEAD, master) Initial commit
Using git commit --amend
command to undo a commit
prompts git to create a new git SHA hash id
for the new commit. This helps to avoid conflicts of SHA hash id’s hence maintaining the transparency of your codes.
The new commit maintains the previous history thus saves you from having to redo the entire process.
Summary
We have covered the following topics in this tutorial on git undo commit:
- Defining git undo commit
- Understanding the git tree
- Git undo commit methods
Further reading