DEV Community

Cover image for How to undo the last commit
Isabel Costa
Isabel Costa

Posted on

Git Revert Pushed Commit How to undo the last commit

In this post I will show how I sometimes recover wrong changes (commits) in a coding project, using git on the command line.

Why would I want to do this?

In my thesis, I’m working on a project that I develop in one environment, and then test in another environment composed of multiple virtual machines. So each important change that I do may have a significant impact on the functionalities of the project. Sometimes, the change I do might not have the result I expected. Then I have to see the changes and analyze the project’s behavior before and after the last commit.

How do you see the last commit?

To test a specific commit, you need the hash. To get the hash you can run git log, then you get this output:

root@debian:/home/debian/test-project# git log
commit <last commit hash>
Author: Isabel Costa <example@email.com>
Date:   Sun Feb 4 21:57:40 2018 +0000

<commit message>

commit <before last commit hash>
Author: Isabel Costa <example@email.com>
Date:   Sun Feb 4 21:42:26 2018 +0000

<commit message>

(...)

You can also run git log --oneline to simplify the output:

root@debian:/home/debian/test-project# git log --oneline
<last commit hash> <commit message>
cdb76bf Added another feature
d425161 Added one feature

(...)

To test a specific commit (e.g.: <before last commit hash>), that you think has the last working version, you can type the following:

git checkout <commit hash>

This will make the working repository match the state of this exact commit. 

After you do this you’ll get the following output:

root@debian:/home/debian/test-project# git checkout <commit hash>
Note: checking out '<commit hash>'.

You are in 'detached HEAD' state. You can look around, make experimental changes
and commit them, and you can discard any commits you make in this state without
impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may do so
(now or later) by using -b with the checkout command again. Example:

git checkout -b new_branch_name

HEAD is now at <commit hash>... <commit message>

After analyzing the specific commit, if you then decide to stay in that commit state, you can undo the last commit.

How to undo this commit?

If you wish to undo/revert the last commit you can do the following, using the commit hash that you get from the git log command:

git revert <commit hash>

This command will create a new commit with the “Revert” word in the beginning of the message. After this, if you check your repository status, you’ll notice that you have the HEAD detached at the commit you tested before.

root@debian:/home/debian/test-project# git status
HEAD detached at 69d885e

(...)

You don’t want to see this message, so to fix this and attach back the HEAD to your working repository, you should checkout the branch you are working on:

git checkout <current branch>

During the making of this post, I found this tutorial — Undoing Commits and Changes —  by Atlassian, which describes very well this issue.

Summary

  • If you want to test the previous commit just do git checkout <test commit hash>; then you can test that last working version of your project.

  • If you want to revert the last commit just do git revert <unwanted commit hash>; then you can push this new commit, which undid your previous commit.

  • To fix the detached head do git checkout <current branch>.


You can find me on Twitter, LinkedIn, Github, Medium and my personal website.

Discussion (17)

Collapse
ghost profile image
Ghost

I do undo differently, in my ~/.gitconfig I have this alias:

[alias]
    undo = reset --soft HEAD~1
Enter fullscreen mode Exit fullscreen mode

Works great!

Collapse
isabelcmdcosta profile image
Isabel Costa Author

Awesome :) more options! I did not know about alias on git.

Collapse
dfockler profile image
Dan Fockler

If you just have a local commit you can also use the git reflog indexes to move back to a point in history even moving back from doing merges and pulls. Something like git reset --hard HEAD@{<reflog index number>}

Collapse
jvarness profile image
Jake Varness

Reflog is life

Collapse
lt0mm profile image
Tom • Edited

also a really powerful command is interactive rebase, though also it changes history for example

git rebase -i HEAD~3

it means you want to make changes in last 3 commits, you can squash them, delete them, change messages, by the way I use it a lot in my feature branches even when I already pushed some commits then I do forced push to rewrite history on the server, it is ok till I know that only I work on that branch

Collapse
saschadev profile image
Der Sascha

For a quick revert you can use git reset HEAD^1 --hard and the you can commit it with additional changes. I thing this "prevents" the revert prefix in the git history. What do you think about it?

Collapse
pshchelo profile image
Pavlo Shchelokovskyy

As long as the commit you are 'undoing' is local and is not part of any remote branch (you have not push-ed it yet), or if this is a one-dev pet project and you are sure nobody is 'consuming' your remote branch (and you can push to it with --force) - git reset is OK.

The thing is - it rewrites history. So if you'll make another commit on top of it but the 'undone' commit is pushed already, the history of your local branch and your remote tracking branch will diverge - and you'd have to push it either to another branch, or with --force, rewriting the remote branch. And if the remote branch is rewritten, anyone who had cloned it won't be able to pull from it any more that easily etc...

Thus the general advise is not to rewrite history of remote branches, and that's what git revert is for.

Funny side note - once seen a commit starting with a word Revert repeated 6 times o_O

Collapse
isabelcmdcosta profile image
Isabel Costa Author

Great explanation! In my case, I thought revert was better because I pushed the previous changes before.

Collapse
isabelcmdcosta profile image
Isabel Costa Author

Thanks for the suggestion. I used that before, but in the last problems where I had to undo the commits and then push the changes, that was the solution that worked for me. Also, I didn't mind having a commit dedicated to the revert (with the prefix) on the git history. I think it is a possible solution too.

Collapse
arandilopez profile image
Arandi López • Edited

You can undo the latest commit with git reset --soft HEAD^ too. But if you already pushed your changes a revert could be a better option.

Collapse
johand profile image
Johan • Edited

I use git reset HEAD~1 to undo the last commit from a local branch and keep the modifications, this is a way for easily fix the changes

Collapse
directfilin profile image
FilinVadim

That is bad. Do not do this.

Collapse
chrisvasqm profile image
Christian Vasquez • Edited

Could you explain why?

Collapse
wiltel492019 profile image
Wiltel492019

Great information that you presented.Commits and changes.Great reach out on your message.

Collapse
reyz_mynick profile image
Roes W

If it's in feature branch I just do hard reset and force push. Revert commit is best solution to revert merge pull request in main/master branch.

Collapse
nelsonblack profile image
Nelson Bwogora • Edited

visual studio git tools you can select undo last commit