796

I cloned a Git repository and then tried to roll it back to a particular commit early on in the development process. Everything that was added to the repository after that point is unimportant to me so I want to omit all subsequent changes from my local source code.

However, when I try to roll back in the GUI tool it doesn't update my local file system - I always end up with the latest source code for the project.

What's the correct way to just get the source for a repository as of a particular commit in the project's history and omit all later updates?

4 Answers4

1258
git reset --hard <tag/branch/commit id>

Notes:

  • git reset without the --hard option resets the commit history, but not the files. With the --hard option the files in working tree are also reset. (credited user)

  • If you wish to commit that state so that the remote repository also points to the rolled back commit do: git push <reponame> -f (credited user)

Retro Gamer
  • 1,096
  • 1
  • 10
  • 24
kauppi
  • 16,966
  • 4
  • 28
  • 19
  • 4
    @MariuszNowak after doing git reset --hard , ( 2 back ) when doing "git push -f origin master" I get "remote: error: denying non-fast-forward refs/heads/master (you should pull first)" it is my repo and I want to take it back :) – peterk Mar 21 '12 at 19:25
  • 17
    @peterk try `--force` at the end of your git push command – Arcolye Apr 03 '12 at 10:07
  • 6
    Make sure you specify the branch name as well. – eipark Jul 14 '12 at 08:06
  • 2
    In server end there is a configuration option for the repository if non-fast-forward pushes are allowed with --force. man git-config and check .git/config for denyNonFastForwards = true in repository. – kauppi Nov 07 '12 at 17:24
  • This doesn't actually work: `fatal: Cannot do hard reset with paths.` – 15ee8f99-57ff-4f92-890c-b56153 Apr 30 '14 at 01:28
  • 3
    The second option for me did not run: I had to do `git push -f master` to restore the remote repository too. However, be aware that with the `-f` switch the commits after the restored commit are also ***LOST*** on the remote repo! (this is what I wanted but someone else may wish to preserve history). – Kounavi Feb 18 '15 at 12:11
  • Hey @kauppi can you please include branchname in git push -f command in your answer? – Devesh Sep 29 '15 at 17:18
  • if your are doing "git reset --hard c9kid83", and want to push changes to same branch run "git push -f", it will also rest your history – Devnegikec Feb 09 '16 at 07:37
  • they thx for your answers: anyone know if: git reset HEAD~2 is different to git reset Head~2 --hard? – BenKoshy Dec 29 '16 at 12:58
  • git reset --hard is what worked for me – Sudhanshu Mishra Mar 21 '17 at 03:39
  • You say "If you wish to **commit** that state you need to ... **push**" - I just have a local repository, so push is not an option. How should that work? – Thomas Weller Jul 05 '17 at 07:40
  • This way does not work for me. remote: error: denying non-fast-forward refs/heads/master (you should pull first) – quantummind Aug 18 '17 at 13:38
  • Is this also possible without using `--force`? You don't always have the possibility to overwrite the history. – TheFox Mar 13 '18 at 16:26
  • Would I permanently loose my newer commits? – Qasim Dec 22 '19 at 02:33
426

Update:

Because of changes to how tracking branches are created and pushed I no longer recommend renaming branches. This is what I recommend now:

Make a copy of the branch at its current state:

git branch crazyexperiment

(The git branch <name> command will leave you with your current branch still checked out.)

Reset your current branch to your desired commit with git reset:

git reset --hard c2e7af2b51

(Replace c2e7af2b51 with the commit that you want to go back to.)

When you decide that your crazy experiment branch doesn't contain anything useful, you can delete it with:

git branch -D crazyexperiment

It's always nice when you're starting out with history-modifying git commands (reset, rebase) to create backup branches before you run them. Eventually once you're comfortable you won't find it necessary. If you do modify your history in a way that you don't want and haven't created a backup branch, look into git reflog. Git keeps commits around for quite a while even if there are no branches or tags pointing to them.

Original answer:

A slightly less scary way to do this than the git reset --hard method is to create a new branch. Let's assume that you're on the master branch and the commit you want to go back to is c2e7af2b51.

Rename your current master branch:

git branch -m crazyexperiment

Check out your good commit:

git checkout c2e7af2b51

Make your new master branch here:

git checkout -b master

Now you still have your crazy experiment around if you want to look at it later, but your master branch is back at your last known good point, ready to be added to. If you really want to throw away your experiment, you can use:

git branch -D crazyexperiment
Neall
  • 26,428
  • 5
  • 49
  • 48
  • 32
    Thanks - might not have been what the poster asked for, but much less anxiety-inducing for me. – Matt Parker Jun 22 '10 at 17:12
  • 9
    Dealing with a remote repository (such as Github), you may have to do a 'git push -f origin master' because of the non-fastforwards to get master to look like it did at the specified commit, but this method is much cleaner than reset. – jcalvert Mar 09 '11 at 16:04
  • 1
    git reset --hard is not that particularly dirty. It is introduced in nearly every git tutorial available as the proper method to undo changes in your own tree. If not in basic features, at least in intermediate ones. If you somehow get into an unknown state/HEAD, there's always git reflog which tells the history of HEAD regardless of branches. Pick a proper commitid from there, and branch from it or git reset --hard with that. – kauppi Jun 17 '11 at 10:57
  • 3
    kauppi - wouldnt you then have issues pushing back to a remote repo? – HaveAGuess Nov 14 '12 at 02:01
  • Reflog is nice when you reset to an earlier commit but then can't find your previous HEAD SHA. – Sebastian Patten Dec 20 '12 at 19:48
  • One more thing: if your old master branch (now renamed to crazyexperiment) was tracking a remote branch, what will happen after the steps in this answer are that crazyexperiment will be tracking that remote branch, and master will not be tracking anything. You might need `git branch --set-upstream-to=/ master` and `git branch --set-upstream-to=/ crazyexperiment` to set those up appropriately – auspicious99 Jan 25 '14 at 09:47
  • 2
    Oops, that should be `git branch --set-upstream master /` and `git branch --set-upstream crazyexperiment /` – auspicious99 Jan 29 '14 at 06:45
  • I followed the instructions here and after doing `git branch -D crazyexperiment` I permanently deleted all my code. I was expecting to get back to the original state, i.e. the state before doing `reset` Posting the commands necessary to restore the backup would be helpful. – 7stud Feb 25 '16 at 09:14
  • +1 for the crazyexperiment, it works without dirtying up the rest of the commits and it's easy to delete the Frankenstein branch – μολὼν.λαβέ Mar 16 '16 at 23:53
  • I did all of this. But how can I merge crazymaster with master branch since technically I don't have any changes? Correct me if i'm wrong but we can only create pull requests if we have any changes, right? – x2ffer12 Feb 28 '23 at 07:58
14

For those with a git gui bent, you can also use gitk.

Right click on the commit you want to return to and select "Reset master branch to here". Then choose hard from the next menu.

ReggieB
  • 8,100
  • 3
  • 38
  • 46
1

When you say the 'GUI Tool', I assume you're using Git For Windows.

IMPORTANT, I would highly recommend creating a new branch to do this on if you haven't already. That way your master can remain the same while you test out your changes.

With the GUI you need to 'roll back this commit' like you have with the history on the right of your view. Then you will notice you have all the unwanted files as changes to commit on the left. Now you need to right click on the grey title above all the uncommited files and select 'disregard changes'. This will set your files back to how they were in this version.

huff
  • 31
  • 2