Log In

How to Undo a Git Commit

How to Undo a Git Commit
27.04.2024
Reading time: 7 min
Hostman Team
Technical writer

One of the most frequent tasks that developers have in their workflow is undoing a git commit. Git offers multiple ways to effectively undo commits without losing the work that has been done, such as fixing an error, going back to an earlier version, or just reorganizing the commit history. Knowing these methods can help maintain a clean and organized library and speed up the development process.

Depending on the user's needs and the commit stage that has to be undone, there are multiple ways in Git to undo a commit. 

Reviewing Git Commit History

Checking the Git commit history is essential for tracking changes, evaluating how a project has evolved, and working productively with other developers. 

For example, a file named file1 was modified in the directory to have a content "hello this is my file". 

To show the changes made on the file, run the command below:

git status

Image4 

A red text with a modified prefix will show on the output to confirm that the file was modified. 

The git status command reports on the repository's current state and assists in monitoring the modifications' progress. It's a helpful tool to understand what's going on in the project before making any modifications. Git displays details about the files that have been edited, files awaiting the next commit, and files that are untracked. 

The git log can also be used to show the commit history of a repository. It shows the list of commits in chronological order, with the most recent commit coming at the top and the oldest at the bottom. 

git log

Image21

This output shows the changes made on the file1 appearing from the most recent changes down to the initial commit done. 

Undoing the Last Commit

To reverse a commit that hasn't been pushed to a remote repository, use the git reset command. It enables "uncommitting" the modifications while preserving them in the working directory by shifting the HEAD pointer to an earlier commit.

The changes committed in the example given above can be undone using the command below. 

git reset --soft HEAD~1

This will roll back the commit and reset back to 1 point while maintaining the code modifications.

To see if the undo took effect, run the command below, this time a green with a modified prefix will show on the output.

git status

Image15

The command's hard reset option will undo all the changes, including the code. Keep in mind that all modifications made with the --hard option will be erased from the working directory, index (the staging area), and the local git repository. Therefore, consider carefully if you want to remove the changes from the working directory as well before using --hard. However, git reset --hard is a really useful tool for rapidly returning your project to a previous state. Run the commands below to do it.

git reset --hard HEAD~1

Image20

Compare the output of git log command both before and after performing the undo. This is to confirm that the undo was successful.

Before: 

Image6

After:

Image17

If no --soft or --hard option is used in git reset, it will default to --mixed. The git reset --mixed command without additional parameters moves the HEAD pointer to the previous commit and unstages the changes, leaving them in the working directory. 

For example, changes were made in the repository by adding a new file named my_new_file and modifying the content  of an existing file named git_revert_demo_file in the same repository.  These changes were applied to the Staging index. The status of the changes can be verified using the command below:

git status

Image5 

To rollback the changes, run the command below. 

git reset --mixed

The output will show that the change is now Unstaged.

Image7

The Staging Index has been reset to a condition where git_revert_demo_file is the only file in the directory. This can be verified by running the git status and git ls-files -s command respectively. 

git status

Image12 

git ls-files -s

Image1

Using git reset --mixed, you also can specify a particular commit to revert to via the HEAD~n parameter where ~n is the notation that specifies the Nth parent commit of the commit referenced by HEAD

In the below example, the working directory git_mixed_test has a file named sample_mixed_test_file with a content "hello git mixed test". The last commit made to the file is "Add content on the file".  To verify, run the command git log.

git log

Image19

To undo the change using git reset --mixed, the parameter HEAD~1 will be used:

git reset --mixed HEAD~1

Image18

Use git log again to view the changes done. Notice that the commit “Add content on the file” is no longer seen on the output.

git log

Image2 

Reverting Specific Commits

To reverse modifications made to a repository's commit history, use the git revert command. Other "undo'" commands that shift the HEAD and branch ref points to a certain commit include git reset. Git revert does not transfer reference points to a defined commit; instead, it accepts a specific commit. A revert operation takes a given commit, reverses its changes, and generates a new "revert commit". The new revert commit is then made the tip of the branch by updating the ref points to point at it.

In this example, there is already a repository created and named git_revert_directory. Three commits have been done to the repository (highlighted in yellow in the screenshot), where the file is named git_revert_demo_file. The contents of the file changed twice (box in red in the screenshot). To view the changes that have been made, run the command below. 

git log

Image3

With the current state of repository, the git revert can now be initiated. Run the command git revert <Hash>. Hash comes after the word “commit” (boxed in blue in the example above). 

git revert 3864b4b4cc81f2d4a648b5f8fff63586b948e1

This command will remove the added line, "prepend content to git_revert_demo_file" to the file git_revert_demo_file.

Image13

After running the git revert command, a default editor will open to allow editing the commit description or leaving and saving it. 

Image10

Git revert does not work without a commit reference, which it expects to be handed in. Here, the HEAD reference has been passed. HEAD in this case is the commit related to “prepend content to git_revert_demo_file”.

Check the state of repository again and verify if revert took effect by running the command below:  

git log

The revert word is shown in the output below (box in red in the screenshot).

Image9

Finally, validate the content of the file git_revert_demo_file. To view it, run the command below. 

cat git_revert_demo_file

Image16

The output should show only the first changes that have been made, which is the content “First Content”. This will confirm that undo was successfully done.

Using Git Reflog for Recovery

The Git reflog (reference log) is a built-in mechanism that stores the history of reference updates in a Git repository. It records any changes to the tip of branches (e.g., commits, branch creations, branch deletions) and other references (e.g., tags, HEAD pointer) throughout time. Essentially, it's a chronological record of all reference pointer movements within the repository. 

To view the reflog for the repository, run the command below.

git reflog show

Image14

This output contains a list of recent reference updates, as well as commit hashes and descriptions of the actions that resulted in the updates. Each entry in the reflog includes a reference to the commits before and after the update, making it simple to identify any changes that were lost or replaced. Run the command below to get a complete reflog of all refs.

git reflog show --all

Image11

Conclusion

To wrap it up, knowing how to undo Git commits is crucial for keeping your repository tidy and orderly, fixing issues quickly, and working well with other developers. By using these methods carefully and combining them with a deep knowledge of Git's workflow, a user can speed up the development process, reduce the chance of data loss, and guarantee the accuracy and integrity of your project's history.


Share