How to use Git Revert

Git

Git Problem Overview


How is git revert used?

This might sound like a duplicate question but when people ask it, the response is often, use git reset as per https://stackoverflow.com/questions/1895059/revert-to-a-commit-by-sha-hash

Then when someone asks how to use git reset people reply saying you should use git revert as per https://stackoverflow.com/questions/19023981/git-how-to-rollback

Before you know it, 8 different people appeared with their own unique ways to save the OP's ass, all of which is over your head.

So lets try and stick the brief and write a Dummies Guide to git revert.

A scenario: you've committed twice to master and its bad. You've pushed and other people have your bad changes.

You want to undo it. It's not something you can hand-undo in code yourself, say some wizard or package manager changed tons of stuff all over the place - you just want to put it all back how it was.

This is what source control is all about. I'm sure its easy.

Okay, you're going to use git revert but how?

And after running git revert do you have to do something else after? Do you have to commit the changes revert made or does revert directly commit to the repo or what??

Obviously you'll need to push again and probably announce your balls-up to the team.

Git Solutions


Solution 1 - Git

git revert makes a new commit

git revert simply creates a new commit that is the opposite of an existing commit.

It leaves the files in the same state as if the commit that has been reverted never existed. For example, consider the following simple example:

$ cd /tmp/example
$ git init
Initialized empty Git repository in /tmp/example/.git/
$ echo "Initial text" > README.md
$ git add README.md
$ git commit -m "initial commit"
[master (root-commit) 3f7522e] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
$ echo "bad update" > README.md 
$ git commit -am "bad update"
[master a1b9870] bad update
 1 file changed, 1 insertion(+), 1 deletion(-)

In this example the commit history has two commits and the last one is a mistake. Using git revert:

$ git revert HEAD
[master 1db4eeb] Revert "bad update"
 1 file changed, 1 insertion(+), 1 deletion(-)

There will be 3 commits in the log:

$ git log --oneline
1db4eeb Revert "bad update"
a1b9870 bad update
3f7522e initial commit

So there is a consistent history of what has happened, yet the files are as if the bad update never occured:

cat README.md 
Initial text

It doesn't matter where in the history the commit to be reverted is (in the above example, the last commit is reverted - any commit can be reverted).

Closing questions

> do you have to do something else after?

A git revert is just another commit, so e.g. push to the remote so that other users can pull/fetch/merge the changes and you're done.

> Do you have to commit the changes revert made or does revert directly commit to the repo?

git revert is a commit - there are no extra steps assuming reverting a single commit is what you wanted to do.

> Obviously you'll need to push again and probably announce to the team.

Indeed - if the remote is in an unstable state - communicating to the rest of the team that they need to pull to get the fix (the reverting commit) would be the right thing to do :).

Solution 2 - Git

Use Git revert like so:

git revert <insert bad commit hash here>

git revert creates a new commit with the changes that are rolled back. git reset erases your Git history instead of making a new commit.

The steps after are the same as any other commit.

Solution 3 - Git

Revert is still confusing people (like me).

As a beginner, after some trial and error (more errors than trials), I've got an important point:

  • git revert requires the id of the commit you want to remove, keeping it into your history

  • git reset requires the commit you want to keep, and will consequentially remove anything after that from history.

That is, if you use revert with the first commit id, you'll find yourself into an empty directory and an additional commit in history, while with reset your directory will be... reverted back to the initial commit and your history will get as if the last commit(s) never happened.

To be even more clear, with a log like this:

# git log --oneline

cb76ee4 wrong
01b56c6 test
2e407ce first commit

Using git revert cb76ee4 will by default bring your files back to 01b56c6 and will add a further commit to your history:

8d4406b Revert "wrong"
cb76ee4 wrong
01b56c6 test
2e407ce first commit

git reset 01b56c6 will instead bring your files back to 01b56c6 and will clean up any other commit after that from your history:

01b56c6 test
2e407ce first commit

I know these are "the basics", but it was quite confusing for me, by running revert on the first id ('first commit') I was expecting to find my initial files, it taken a while to understand, that if you need your files back as 'first commit' you need to use the next id.

Solution 4 - Git

The reason reset and revert tend to come up a lot in the same conversations is because different version control systems use them to mean different things.

In particular, people, who are used to Subversion or Perforce, who want to throw away uncommitted changes to a file, will often reach for revert before being told that they actually want reset.

Similarly, the revert equivalent in other VCSes is often called rollback or something similar - but "rollback" can also mean "I want to completely discard the last few commits", which is appropriate for reset but not revert. So, there's a lot of confusion where people know what they want to do, but aren't clear on which command they should be using for it.

As for your actual questions about revert...

> Okay, you're going to use git revert but how?

git revert first-bad-commit^..last-bad-commit

Note the ^ character for the first-bad-commit. This is referencing the parent of first-bad-commit, because the revert range does not include the starting commit.

> And after running git revert do you have to do something else after? Do you have to commit the changes revert made or does revert directly commit to the repository or what??

By default, git revert prompts you for a commit message and then commits the results. This can be overridden. I quote the man page:

> --edit > > With this option, git revert will let you edit the commit message prior to committing the revert. This is the default if you run the command from a terminal. > > --no-commit > > Usually the command automatically creates some commits with commit log messages stating which commits were reverted. This flag applies the changes necessary to revert the named commits to your working tree and the index, but does not make the commits. In addition, when this option is used, your index does not have to match the HEAD commit. The revert is done against the beginning state of your index. > > This is useful when reverting more than one commits' effect to your index in a row.

In particular, by default it creates a new commit for each commit you're reverting. You can use revert --no-commit to create changes reverting all of them without committing those changes as individual commits, and then commit at your leisure.

Solution 5 - Git

I reverted back a few commits by running 'git revert commit id' such as:

git revert b2cb7c248d416409f8eb42b561cbff91b0601712

Then I was prompted to commit the revert (just as you would when running 'git commit'). My default terminal program is Vim, so I ran:

:wq 

Finally, I pushed the change to the repository with:

git push

Solution 6 - Git

The below infographic is showing how git revert is essentially an inverted git cherry-pick, undoing stuff by rolling forward; the target commit being reverted stays in history!

Use git revert when you cannot rewrite the entire history, but still want to undo an earlier commit completely. As with most Git commands, revert is performed locally, and hence, the resulting commit needs to be pushed in order to be shared with the rest of your team.

Infographic showing how

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLuke PuplettView Question on Stackoverflow
Solution 1 - GitAD7sixView Answer on Stackoverflow
Solution 2 - GitJohnny ZView Answer on Stackoverflow
Solution 3 - GitnnsenseView Answer on Stackoverflow
Solution 4 - GitToxicFrogView Answer on Stackoverflow
Solution 5 - Gitjrc16View Answer on Stackoverflow
Solution 6 - GitAlexis Määttä VinklerView Answer on Stackoverflow