309

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 Revert to a commit by a SHA hash in Git?.

Then when someone asks how to use git reset people reply saying you should use git revert as per Git - how to rollback.

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

So let’s try and stick the brief and write a Dummies Guide to git revert.

A scenario: you've committed twice to master and it’s 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 it’s 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 repository or what??

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

2
  • 1
    My IDE just asked whether to --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-edit With this option, git revert will not start the commit message editor. From the Docs.
    – cachius
    Commented Sep 29, 2022 at 13:05
  • 1
    I wish I could add an extra +1 just for using "balls-up" in your question.
    – CDahn
    Commented May 9 at 12:29

7 Answers 7

285

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 your balls-up 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 :).

7
  • By way of confirmation, both to the first statement here and to anyone wondering the same thing I just wondered about how it works, you can revert a revert, where there are several new commits since the revert you're reverting. So revert truly is just a commit of the opposite of the reverted commit. You might, of course, have conflicts ... but that's a different story.
    – GG2
    Commented May 10, 2019 at 19:02
  • 2
    I always find it better to avoid commit with it,just to review the changes first and I use, git revert -n <commitToRevet> or git revert --no-commit <commitToRevet>
    – Eklavyaa
    Commented Jul 30, 2019 at 5:27
  • 12
    Just wanted to say that after years on stackoverflow, I think this may be one of the best answers I've ever come across. Great example and explanation.Thank you. Commented Aug 2, 2019 at 14:18
  • I got into here expecting to get more information, something like a TLDR of this raw.githubusercontent.com/git/git/master/Documentation/howto/…
    – wviana
    Commented Mar 22, 2020 at 20:16
  • 5
    @wviana If the information you've found is insufficient please write an answer. Note that stack overflow is no substitute for the official documentation (which you appear to be linking to, and covers a much broader scope than this question).
    – AD7six
    Commented Mar 23, 2020 at 9:10
97

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.

1
  • 3
    The difference between "revert a commit" and "revert TO a commit" is subtle enough that I've struggled with this command for years. Your explanation resolved it for me instantly. Thanks!
    – claviska
    Commented Jan 17, 2020 at 21:23
88

The question is quite old but 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 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.

1
  • 2
    I have observed the same. its really confusing but so important to know. just recently i had to help an coworker and forgot about this. That was a bit embarrassing.
    – ExOfDe
    Commented May 13, 2020 at 7:24
31

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.

2
  • 2
    git revert first-bad-commit..last-bad-commit: I think this should be git revert parent-of-first-bad-commit..last-bad-commit. Commented Sep 20, 2019 at 13:47
  • 2
    @user1071847 is right. The range syntax was wrong. I placed an edit to fix it.
    – itsafire
    Commented Apr 29, 2021 at 12:09
5

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
3

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 "git revert" is essentially an inversed "git cherry-pick", undoing stuff by rolling forward

3
git revert HEAD~x --no-edit

--no-edit to skip the commit message editor

x is a number .it says the number of steps you want to go back .

Not the answer you're looking for? Browse other questions tagged or ask your own question.