Rolling back local and remote git repository by 1 commit

I've read the similar posts on this topic, and can't for the life of me figure out how to do this properly.

I checked in about 1000 files that I don't want, and I'd rather not have to go through 1by1 and remove them all from the repo.

  • I have a remote master Branch.
  • I have the local master Branch.

They are both at the same revision.

I want to rollback my remote by 1 commit.

Say my history on master is A--B--C--D--E.
I want to rollback my local to D.
Then push it to remote so my current hash will be D both remote and local.

I'm having issues doing this.
I'm using Git Tower but am comfortable with the command line. Any help?

UPDATE: Great comments below. Using a reset seems to be partially discouraged especially if the repository is shared with other users. What's the best way to undo the previous commit's changes without using a hard reset? Is there a way?


If nobody has pulled your remote repo yet, you can change your branch HEAD and force push it to said remote repo:

git reset --hard HEAD^ 
git push -f 

(or, if you have direct access to the remote repo, you can change its HEAD reference even though it is a bare repo)

Note, as commented by alien-technology in the comments below, on Windows (CMD session), you would need ^^:

git reset --hard HEAD^^
git push -f 

And? as noted in the comments by Jon Schneider:

If the command with "HEAD^" results in error no matches found: HEAD^, see "git show HEAD^ doesn't seem to be working. Is this normal?"

Update since 2011:
Using git push --force-with-lease (that I present here, introduced in 2013 with Git 1.8.5) is safer.

See Schwern's answer for illustration.


What if somebody has already pulled the repo? What would I do then?

Then I would suggest something that doesn't rewrite the history:

  • git revert locally your last commit (creating a new commit that reverses what the previous commit did)
  • push the 'revert' generated by git revert.

Set the local branch one revision back (HEAD^ means one revision back):

git reset --hard HEAD^

Push the changes to origin:

git push --force

You will have to force pushing because otherwise git would recognize that you're behind origin by one commit and nothing will change.

Doing it with --force tells git to overwrite HEAD in the remote repo without respecting any advances there.


If you want revert last commit listen:

Step 1:

Check your local commits with messages

$ git log

Step 2:

Remove last commit without resetting the changes from local branch (or master)

$ git reset HEAD^

OR if you don't want last commit files and updates listens

$ git reset HEAD^ --hard

Step 3:

We can update the files and codes and again need to push with force it will delete previous commit. It will keep new commit.

$ git push origin branch -f

That's it!


Here's an updated version of the procedure which is safer.

git reset --hard HEAD^ 
git push --force-with-lease

git push -f will indiscriminately replace the remote repository with your own changes. If someone else has pushed changes they will be lost. git push --force-with-lease will only push your rebase if the repository is as you expect. If someone else has already pushed your push will fail.

See –force considered harmful; understanding git’s –force-with-lease.

I recommend aliasing this as repush = push --force-with-lease.

What if somebody has already pulled the repo? What would I do then?

Tell them to git pull --rebase=merges. Instead of a git fetch origin and git merge origin/master it will git fetch origin and git rebase -r origin/master. This will rewrite any of their local changes to master on top of the new rebased origin/master. -r will preserve any merges they may have made.

I recommend making this the default behavior for pulling. It is safe, will handle other's rebasing, and results in less unnecessary merges.

[pull]
        rebase = merges