[git] Rollback to an old Git commit in a public repo

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.

This question is related to git git-checkout git-revert

The answer is


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.


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.


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.


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.


Here is an example to do that

    cd /yourprojects/project-acme 


    git checkout efc11170c78 .

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


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.


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


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 <[email protected]>
Date:   Fri Jul 8 23:42:22 2016 +0300

This is last commit message

commit fd6cb176297acca4dbc69d15d6b7f78a2463482f
Author: author <[email protected]>
Date:   Fri Jun 24 20:20:24 2016 +0300

This is previous commit message

commit ab0de062136da650ffc27cfb57febac8efb84b8d
Author: author <[email protected]>
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.


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?


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

Examples related to git

Does the target directory for a git clone have to match the repo name? Git fatal: protocol 'https' is not supported Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) git clone: Authentication failed for <URL> destination path already exists and is not an empty directory SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 GitLab remote: HTTP Basic: Access denied and fatal Authentication How can I switch to another branch in git? VS 2017 Git Local Commit DB.lock error on every commit How to remove an unpushed outgoing commit in Visual Studio?

Examples related to git-checkout

How can I switch to another branch in git? Git checkout - switching back to HEAD What is git tag, How to create tags & How to checkout git remote tag(s) How can I move HEAD back to a previous location? (Detached head) & Undo commits error: pathspec 'test-branch' did not match any file(s) known to git git checkout all the files How can I check out a GitHub pull request with git? "Cannot update paths and switch to branch at the same time" error: Your local changes to the following files would be overwritten by checkout Git command to checkout any branch and overwrite local changes

Examples related to git-revert

How to undo the last commit in git How can I move HEAD back to a previous location? (Detached head) & Undo commits How to undo local changes to a specific file How do I use 'git reset --hard HEAD' to revert to a previous commit? What's the difference between Git Revert, Checkout and Reset? Why does git revert complain about a missing -m option? How to revert uncommitted changes including files and folders? Reset all changes after last commit in git How do I revert a Git repository to a previous commit? Undo a particular commit in Git that's been pushed to remote repos