DEV Community

Cover image for How to undo git commits? Locally & Remotely.
John J Davidson
John J Davidson

Posted on • Edited on

How to undo git commits? Locally & Remotely.

TL:DR ⏩

  1. In the repo, open a new terminal window
  2. Enter this command: git log --oneline --decorate --graph
  3. Find the commit hash you want to revert the repo to.
  4. Enter this command: git reset --hard theHashOfTheCommitHere

Example: git reset --hard 0ffbffgs3

  1. Then enter: git clean -f -d
  2. Finely you need to force push the reset repo to the remote with this command: git push -f

To exit git at any time you and type q next to the colon at the bottom of your CLI.

In summary:

git log --oneline --decorate --graph
git reset --hard xxxxx
git clean -f -d
git push -f

 
 

Long version. ⬇️

At some point, you'll be commit something to a repo that you look back and wish you didn't commit that feature/bug fix/OnlyFans video.

So when that happens and you have even pushed the commit to remote, what should you do?

How do you undo git commits?

Locally & remotely.

 
 

Step #1: git log --oneline --decorate --graph

 
 

You need to explore your git repo and the status of it. This is so we can find the hash number for the commit you want to revert back too.

You need to open the repo in your terminal/command line interface (CLI) inside of your working repo directory and in the branch you want to reset the commit on. You can enter this command:

 

git log --oneline --decorate --graph

 

This will output/display this in your terminal:

git log in oneline, decorate, graph

Let's break this command down to better understand it.

To exit git at any time you can type q next to the colon at the bottom of your CLI.

 

If you don't need to know the break down of the command, go to:  
Step #2: git reset --hard xxxxx

 

git log

 

This part simply gives you a record or log of all the commits you have created in this repo. However unlike the above screen shot which lists them all on one line.

This gives you very detailed description of your git commits.

Detailed description of your git commits

git log --oneline

 

This is the first flag in the command and is used to format the output of the log. if you do not use this the output log would look like this:

No --oneline
 

Detailed description of your git commits

With --oneline
 

git log in oneline

Git Documentation says:
This is a shorthand for "--pretty=oneline --abbrev-commit" used together.

git log --oneline --decorate

 

The second flag in the command is another formatting flag, that will highlight what Git Reference you are on and there are some options you can added to the end of --decorate such as --decorate[=short|full|auto|no]

Git references are bit out of the scope for this tutorial, however if you are aware of them, you may find this part a useful flag.

Here is a small demo of the command.

git log --oneline --decorate=short
 

Output of git log --oneline --decorate=short

git log --oneline --decorate=full
 

Output of git log --oneline --decorate=full

--decorate[=short|full|auto|no]
Print out the ref names of any commits that are shown.

git log --oneline --decorate --graph

 

--graph is the third and last flag in the command. It is a non essential flag, but will allow for a bit of a nice formatting so you can visualize your git log better.

Specifically it will deal with commits you have merged from other branches and show that merge in a graphical text based visualization.

No --graph
 

Output of git log --oneline --decorate

With --graph
 

Output of git log --oneline --decorate --graph

And that is what, git log --oneline --decorate --graph does.

 
 

Step #2: git reset --hard xxxxx

 
 

Now you have the commit hash you need and now it is time to reset your working git branch to the commit you want to revert back too.

To do this, you need to do use the command:

git reset --hard xxxxx
 

--hard
Resets the index and working tree. Any changes to tracked files in the working tree since are discarded. Any untracked files or directories in the way of writing any tracked files are simply deleted. Source: git-reset Documentation

What does that mean? Well you have to compare this command to:

git reset --soft xxxxx
 

Let's look at the CLI/terminal in VScode in a working repo and compare the two.

With: git reset --soft xxxxx
 

Using git reset --soft

When using --soft as a mode you will reset the working directory to the requested commit, however all the changes in the commits after the requested commit will undo, and become staged changes in the repo. As seen above.

With: git reset --hard xxxxx
 

Using git reset --hard

The working directory is now completely clear of all commits after the reset to the requested commit, and there is no staged changes, the commits are gone. This is irreversible.

 
Well kind of irreversible...
 

If you notice at the bottom of the above screenshot you'll see this:

A screen shot of a pull from orign

I still have one commit to pull from remote. As you guessed it. It is the one I just reset. At this point your local working directory has been reset, and if that is all you need to do. Then you have finished. But...

the reset commit added back to repo

...how do you reset a commit when you have already pushed it remotely?

 
 

Step #3: git clean -f -d

 
 

Step back and make sure you have used the command:
git reset --hard xxxxx

After that you can safely move on to the git clean.

https://www.git-scm.com/docs/git-clean

-d

Normally, when no is specified, git clean will not recurse into untracked directories to avoid removing too much. Specify -d to have it recurse into such directories as well. If any paths are specified, -d is irrelevant; all untracked files matching the specified paths (with exceptions for nested git directories mentioned under --force) will be removed.

-f
--force

If the Git configuration variable clean.requireForce is not set to false, git clean will refuse to delete files or directories unless given -f or -i. Git will refuse to modify untracked nested git repositories (directories with a .git subdirectory) unless a second -f is given.

These two descriptions of the -d & -f flag are quite indepth. But to help with a jist what they are doing along with git clean.

They will first tell git to clean the working directory of any and all untracked files, using the flag -d will say that you have not specified a path and -f will tell git "just do it, don't warn me" because once done this can not be un done.

 
 

Step #4: git push -f

 
 

--force

...This flag disables these checks, and can cause the remote repository to lose commits; use it with care.

The above description covers the git push -f quite well, however it warns us that we should use this command with care and we should, but this is the part where we want git to overwrite the existing commit on the remote repo. We want to undo a commit remotely. but to use this command is the final step. once done the commit is undone and you no longer need to do or change anything else.

git push -f

You have now undone a commit remotely.

🥳 Congratulations! 🥳

Any questions or queries. Please let me know in the comments.

Any feedback is appreciated as well!

Top comments (0)