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 inerror 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