935

How can I go about rolling back to a specific commit in git?

The best answer someone could give me was to use git revert X times until I reach the desired commit.

So let's say I want to revert back to a commit that's 20 commits old, I'd have to run it 20 times.

Is there an easier way to do this?

I can't use reset because this repository is public.

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42
David
  • 9,799
  • 5
  • 28
  • 32
  • 1
    git revert does not work? – miku Jan 05 '10 at 17:04
  • 9
    As stated in my question, this really doesn't help me if i want to revert back to something 20 commits ago. – David Jan 05 '10 at 19:20
  • 8
    This question has been quite well answered here http://stackoverflow.com/questions/4114095/revert-to-previous-git-commit – user7610 Jan 29 '14 at 21:45
  • 6
    It's not clear what you mean by "rolling back". Does that mean you want to temporarily switch your working copy to a particular revision? Or you do want to permanently revert the history of your repository back to a certain revision? –  Apr 21 '14 at 19:48
  • 2
    You should accept an answer, and possibly vote up the any other answers you like. – Nabil Kadimi Aug 09 '14 at 16:59
  • Related: [Revert Git repo to a previous commit](http://stackoverflow.com/q/4114095/456814). Note that that question doesn't have the constraint that the repo is public. –  Oct 19 '15 at 09:51

13 Answers13

1365

Try this:

git checkout [revision] .

where [revision] is the commit hash (for example: 12345678901234567890123456789012345678ab).

Don't forget the . at the end, very important. This will apply changes to the whole tree. You should execute this command in the git project root. If you are in any sub directory, then this command only changes the files in the current directory. Then commit and you should be good.

You can undo this by

git reset --hard 

that will delete all modifications from the working directory and staging area.

Sunil Kumar
  • 6,112
  • 6
  • 36
  • 40
Alex Reisner
  • 29,124
  • 6
  • 56
  • 53
  • 9
    @AlexReisner That period at the end points at the directory you are currently in, which is not necessarily the entire git project, correct? If you wanted to apply the changes to the whole project, would you instead use ':/' like in 'git add :/', if you were not currently in the git project root? – MSpreij Apr 16 '13 at 21:39
  • 13
    note: if you have added new files to your project since then, this won't delete them. So when you go to build (depending on your platform), you may get errors still. Delete the new files and you're good to go. – TheWestIsThe... Oct 09 '13 at 17:31
  • 7
    @MSpreij You should execute this command in the git project root. If you are in any sub directory, then this command only changes the files in the current directory. – volatilevar Aug 04 '14 at 19:50
  • 3
    Its great when you can clone a project in another directory and use git checkout [revision] . to get back to a specific revision and then compare it with the same project in other directory. Saves a lot of time. – Daniel Viglione Jun 09 '16 at 20:16
  • 4
    Damnit, I forgot the "." what damage have I do to my repository ? – Owl Dec 07 '16 at 15:22
  • 1
    Also if you want to reset to one commit before that commit, you can do: `git checkout [revision]~1 .` – Hendrik Dec 13 '16 at 08:37
  • 2
    Why the semicolon at the end of `git reset --hard;`? – Stefan Monov Apr 21 '17 at 12:40
  • How can I tell if this command ran successfully? `git log -1` gives a deceptive answer. – John Red Apr 28 '17 at 09:01
  • 3
    `git checkout [revision] .` didn't work for me, nothing happened. – coder.chenzhi Apr 20 '18 at 04:46
  • 1
    `git reset --hard;` is not giving me back my newer commits – Gabriel Jul 27 '18 at 17:36
  • 1
    Nope. This doesn't work for me. It just creates a detached HEAD. That's not a rollback. A rollback means changing the current branch so that newer commits are lost. – geoidesic May 20 '19 at 02:29
  • 1
    `git checkout ` worked even without the `.` at the end for me. According to the git documentation, it will also change files in the working tree. So the `.` appears to be redundant. – Johannes Schaub - litb Jul 15 '19 at 11:32
  • 1
    @geoidesic did you forget the dot. If you don't add the dot, it will give you a detached head and expects you to create a new branch from there on to attach the head – mithunpaul Dec 09 '19 at 02:29
  • So, stupid to use this long values that you have to lookup first. Why not rollback 1 to rollback one commit. To make it easy to navigate... – Soerendip Sep 18 '21 at 01:26
238

To rollback to a specific commit:

git reset --hard commit_sha

To rollback 10 commits back:

git reset --hard HEAD~10

You can use "git revert" as in the following post if you don't want to rewrite the history

How to revert Git repository to a previous commit?

Community
  • 1
  • 1
Naga Kiran
  • 8,585
  • 5
  • 43
  • 53
  • 5
    only difference between this approach and "git checkout [revision] ." is that the latter preserves revisions. – deeshank Feb 09 '14 at 04:09
  • 63
    This answer is WRONG as OP specifically states "I can't use reset cause this repo is public" – Yarin Feb 12 '14 at 01:02
  • 5
    If repo is public, I think there is no way to rollback the commit on public repository without using force push (git push -f) as it will affect the people who have pulled in the changes before rollback. So, reset can be used in local sandbox of a public repo also. – Naga Kiran Feb 17 '14 at 07:23
  • 4
    It's great that this avoids a detached HEAD! Just what I was looking for. – cyber-monk Jan 19 '17 at 21:30
  • 2
    In my case this worked, then use 'git pull' to fast forward back to head after you've tested regressions,etc. – Peter Quiring Mar 16 '18 at 14:22
  • 3
    @Yarin the answer is GOOD, the premises of OP are WRONG that he can't use reset on public repo. He can. Sorry for necromancy comment ;) – 9ilsdx 9rvj 0lo Jul 10 '18 at 07:43
  • The problem with `git reset --hard SHA` is that you can't push it to a public remote as is. You will have to merge and then push it. The other answer of `git checkout SHA .` worked for me – mithunpaul Dec 09 '19 at 02:31
  • This answer worked for me over the most voted. I was waiting for a commit to come down and had made a commit on the server which i realised I can't push up as I have read-only access to the main repo. I needed to ditch my local commit, reset my branch and pull in the correct changes. The above `git checkout` method didn't work for me. Even after doing git reset, It just kept wanting to do a `git merge`. This is because it was resetting against the latest HEAD commit. This solution was ideal, reset a couple of commits back, did a git pull and i successfully tidied my branch. – Harvey Dobson Jun 19 '20 at 17:02
98

Well, I guess the question is, what do you mean by 'roll back'? If you can't reset because it's public and you want to keep the commit history intact, do you mean you just want your working copy to reflect a specific commit? Use git checkout and the commit hash.

Edit: As was pointed out in the comments, using git checkout without specifying a branch will leave you in a "no branch" state. Use git checkout <commit> -b <branchname> to checkout into a branch, or git checkout <commit> . to checkout into the current branch.

Ben
  • 6,857
  • 26
  • 23
  • 3
    Doesn't this put you into the weird 'Not currently on any branch' state? How do you commit changes to complete the rollback? – Alex Reisner Jan 05 '10 at 17:13
  • Well, I'm just suggesting the use of `git checkout` -- he's free to check out into any branch (current or new) that he wishes. I'll update my answer so it's not ambiguous. – Ben Jan 05 '10 at 17:25
  • 3
    I tried this but I don't think this is the proper way to do it cause it leaves stagnate files. This doesn't delete files that weren't in that last commit. – David Jan 05 '10 at 17:49
  • 3
    If you're in a working directory and you're staying in master, you need `git reset` to delete those files, which you say you don't want to do. Try doing it into a separate branch: `git checkout -b `, you won't have stagnant files *in that branch*. – Ben Jan 05 '10 at 19:10
  • that's definitely one solution. What about if someone were to write a bash script that would accept would run reverts until the desired hash is reached. – David Jan 08 '10 at 21:13
  • 2
    The problem with using `checkout` is that it won't delete files that were added in a previous commit. –  Apr 21 '14 at 20:00
44

The original poster states:

The best answer someone could give me was to use git revert X times until I reach the desired commit.

So let's say I want to revert back to a commit that's 20 commits old, I'd have to run it 20 times.

Is there an easier way to do this?

I can't use reset cause this repo is public.

It's not necessary to use git revert X times. git revert can accept a commit range as an argument, so you only need to use it once to revert a range of commits. For example, if you want to revert the last 20 commits:

git revert --no-edit HEAD~20..

The commit range HEAD~20.. is short for HEAD~20..HEAD, and means "start from the 20th parent of the HEAD commit, and revert all commits after it up to HEAD".

That will revert that last 20 commits, assuming that none of those are merge commits. If there are merge commits, then you cannot revert them all in one command, you'll need to revert them individually with

git revert -m 1 <merge-commit>

Note also that I've tested using a range with git revert using git version 1.9.0. If you're using an older version of git, using a range with git revert may or may not work.

In this case, git revert is preferred over git checkout.

Note that unlike this answer that says to use git checkout, git revert will actually remove any files that were added in any of the commits that you're reverting, which makes this the correct way to revert a range of revisions.

Documentation

  • 1
    **Note**: this **creates a new commit** with the reverted changes. Perfect for OP's question. But make sure that's what you want. (The examples in the *git-revert* doc linked to above is excellent.) If you instead wish to investigate prior commits (ie before choosing what commit to revert to) use the checkout option mentioned in other answers, keeping in mind the comments others have made about deleted files. – SherylHohman Jan 27 '18 at 17:11
  • 1
    @SherylHohman Reverting back to a previous commit doesn't create a new commit. I can't imagine what you mean here. –  Jul 12 '18 at 08:40
38

Step 1: fetch list of commits:

git log

You'll get list like in this example:

[Comp:Folder User$ git log
commit 54b11d42e12dc6e9f070a8b5095a4492216d5320
Author: author <author@gmail.com>
Date:   Fri Jul 8 23:42:22 2016 +0300

This is last commit message

commit fd6cb176297acca4dbc69d15d6b7f78a2463482f
Author: author <author@gmail.com>
Date:   Fri Jun 24 20:20:24 2016 +0300

This is previous commit message

commit ab0de062136da650ffc27cfb57febac8efb84b8d
Author: author <author@gmail.com>
Date:   Thu Jun 23 00:41:55 2016 +0300

This is previous previous commit message
...

Step 2: copy needed commit hash and paste it for checkout:

git checkout fd6cb176297acca4dbc69d15d6b7f78a2463482f

That's all.

Igor
  • 12,165
  • 4
  • 57
  • 73
  • And this affects only your local, right? I need to find where a bug occurred, and was going to use this approach to keep getting different commits until the error went away. I only want to change my local though; not remote. – Bob Horn Jun 23 '20 at 13:39
14

Want HEAD detached mode?

If you wish to rollback X time to a certain commit with a DETACHED HEAD (meaning you can't mess up anything), then by all means, use the following:

(replace X with how many commits you wish to go back)

git checkout HEAD~X

I.E. to go back one commit:

git checkout HEAD~1
Shiva Prasad
  • 430
  • 2
  • 12
basickarl
  • 37,187
  • 64
  • 214
  • 335
11
git read-tree -um @ $commit_to_revert_to

will do it. It's "git checkout" but without updating HEAD.

You can achieve the same effect with

git checkout $commit_to_revert_to
git reset --soft @{1}

if you prefer stringing convenience commands together.

These leave you with your worktree and index in the desired state, you can just git commit to finish.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • This is the only straightforward approach that worked like a charm! I checked out from head, ran this command, and it successfully removed added files that we had introduced and reverted all the changes. Excellent. – kamranicus Mar 16 '18 at 14:05
3

Let's say you work on a project and after a day or so. You notice one feature is still giving you errors. But you do not know what change you made that caused the error. So you have to fish previous working commits. To revert to a specific commit:

git checkout 8a0fe5191b7dfc6a81833bfb61220d7204e6b0a9 .

Ok, so that commit works for you. No more error. You pinpointed the issue. Now you can go back to latest commit:

git checkout 792d9294f652d753514dc2033a04d742decb82a5 .

And checkout a specific file before it caused the error (in my case I use example Gemfile.lock):

git checkout 8a0fe5191b7dfc6a81833bfb61220d7204e6b0a9 -- /projects/myproject/Gemfile.lock

And this is one way to handle errors you created in commits without realizing the errors until later.

Daniel Viglione
  • 8,014
  • 9
  • 67
  • 101
3

You can find the commit id related to each commit in the commits section of GitHub/BitBucket/Gitlab. Its very simple, suppose your commit id is 5889575 then if you want to go back to this part in your code then you simply need to type

git checkout 5889575 .

This will take you to that point of time in your code.

Naved Ahmad
  • 783
  • 8
  • 7
2

I'm not sure what changed, but I am unable to checkout a specific commit without the option --detach. The full command that worked for me was: git checkout --detach [commit hash]

To get back from the detached state I had to checkout my local branch: git checkout master

ken
  • 161
  • 1
  • 8
  • Checking out `master` resolves the problem of remaining detached, while doing `git reset --hard` or `git checkout -- .` did worked but remained detached – DarkCygnus May 17 '17 at 18:06
1

Here is an example to do that

    cd /yourprojects/project-acme 


    git checkout efc11170c78 .
mcvkr
  • 3,209
  • 6
  • 38
  • 63
0

to rollback a specific commit in git:

  • to get back an old git commit: (the ac2ec... is the commit name)
git checkout ac2ece0219689ed86b08c93dfebb0d02c0f1d5b1
  • name a new branch that you want the HEAD detach will point to:
git branch get_back_to_past
  • checkout to that branch
git checkout get_back_to_past

now that branch has the past commit items. you can merge it to the master for example if you would like to.

for more info about git head, and rollback to old version: click here

0

on the Github find the commit you made and checkout to it.

git checkout <commit#>

example: git checkout b29ce12

enter image description here

Cugomastik
  • 911
  • 13
  • 22