807

Here's what I did on my supposed-to-be-stable branch...

% git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded alpha-0.3.0 to master.
% git status
# On branch alpha-0.3.0
# Your branch is ahead of 'origin/alpha-0.3.0' by 53 commits.
#
nothing to commit (working directory clean)
% git push
Fetching remote heads...
  refs/
  refs/heads/
  refs/tags/
  refs/remotes/
'refs/heads/master': up-to-date
updating 'refs/heads/alpha-0.3.0'
  from cc4b63bebb6e6dd04407f8788938244b78c50285
  to   83c9191dea88d146400853af5eb7555f252001b0
    done
'refs/heads/unstable': up-to-date
Updating remote server info

That was all a mistake as I later realized. I'd like to undo this entire process, and revert the alpha-0.3.0 branch back to what it was.

What should I do?

BryanH
  • 5,826
  • 3
  • 34
  • 47
khosrow
  • 8,799
  • 4
  • 21
  • 24
  • this stackoverflow post perhaps? http://stackoverflow.com/questions/134882/undoing-a-git-rebase – Steen Feb 24 '11 at 03:27
  • 7
    It's not really the same situation, undoing a rebase is a local repository scenario, undoing a git push involves a remote repository and can be more tricky depending on the access you have. – CB Bailey Feb 24 '11 at 03:27
  • Steen - you're right - I probably should have I suppose. I figured that the blessed repository that all pull from is more of an admin task and so belongs here, where general client-side git is a stackoverflow question. – khosrow Feb 24 '11 at 03:27
  • Quick clarification - I'm guessing if you refer to a git commit by a *partial* hash value, git will assume you're talking about the commit whose hash begins with that string? – Gershom Maes Nov 27 '15 at 16:32

16 Answers16

1267

You need to make sure that no other users of this repository are fetching the incorrect changes or trying to build on top of the commits that you want removed because you are about to rewind history.

Then you need to 'force' push the old reference.

git push -f origin last_known_good_commit:branch_name

or in your case

git push -f origin cc4b63bebb6:alpha-0.3.0

You may have receive.denyNonFastForwards set on the remote repository. If this is the case, then you will get an error which includes the phrase [remote rejected].

In this scenario, you will have to delete and recreate the branch.

git push origin :alpha-0.3.0
git push origin cc4b63bebb6:refs/heads/alpha-0.3.0

If this doesn't work - perhaps because you have receive.denyDeletes set, then you have to have direct access to the repository. In the remote repository, you then have to do something like the following plumbing command.

git update-ref refs/heads/alpha-0.3.0 cc4b63bebb6 83c9191dea8
Roshan Bhumbra
  • 540
  • 1
  • 8
  • 17
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 25
    A perfect and well explained response - thank you very much. For anyone else who stumbles accross this, for academic reasons I tried both of the first 2 approaches, and both worked - obviously if the first one works, it's the cleanest approach. If I chould UP you 10 times Charles, I would. :) – khosrow Aug 13 '09 at 08:51
  • 159
    For quick-reference, the first line here is `git push -f origin last_known_good_commit:branch_name` – philfreo Aug 29 '11 at 23:16
  • 7
    git push -f origin cc4b63bebb6:alpha-0.3.0 => this one helped me, Note alpha-0.3.0 is the branch name and cc4b63bebb6 is the commit id we wish to revert back to. so, after carrying out this command we wil be in cc4b63bebb6 commit id. – kumar Dec 28 '11 at 11:51
  • 28
    This solution is highly dangerous if you are working in a shared repo. As a best practice, all commits pushed to a remote repo that is shared should be considered 'immutable'. Use 'git revert' instead: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#fixing-mistakes – Saboosh Jan 13 '12 at 20:47
  • 3
    jww - compared to everything else, git is the most feature-rich and efficient source control tool available. Every team uses it differently. It's worth spending a weekend playing around with a fresh repository and going through all the common scenarios. Once you've spent some time working with it, development is a lot less stressful. – user1491819 Oct 23 '15 at 04:29
  • 2
    What if others have fetched? – aateeque Nov 27 '15 at 15:29
  • 2
    this forget to mention that, you loose any local work in the process. I wrongfully had pushed to the wrong branch some changes did this git push -f and loose my previous local changes :p Thanks you IntelliJ for the Local History feature saved my ass :p – forcewill Mar 22 '17 at 11:52
  • Not worked with **LFS**: after trivial push like `git push -f origin good_commit:master` it returns an error message, *"Locking support detected on remote 'origin'. Consider enabling it with: `$ git config 'lfs.github.com/authority/project.git/info/lfs.locksverify'; true`"*... After the suggested `git config` worked fine (!), important to do `git config ... false` after all, to back to normal LDF activity. – Peter Krauss Feb 19 '18 at 18:39
  • WHAT A SAVE!!! I had code that hadn't been committed in one repository and wanted to push changes I made in another, but GitHub Desktop was in the wrong repository and I pushed the not ready changes instead. – Xbox One Jul 30 '22 at 16:17
  • 1
    After executing the `git push -f`, remember to do also a `git reset --hard ` to "undo" changes in your local repository too. – Ricky Sixx Aug 02 '22 at 12:38
219

I believe that you can also do this:

git checkout alpha-0.3.0
git reset --hard cc4b63bebb6
git push origin +alpha-0.3.0

This is very similar to the last method, except you don't have to muck around in the remote repo.

Benny Wong
  • 6,773
  • 5
  • 31
  • 25
  • 14
    This worked for me as well, but it's worth noting that this will "re-write" history on the remote. This may be what you want, but it may not be! – Tom Aug 25 '11 at 17:09
  • 4
    +1 for this answer that really helped me out. I also wanted to add (and make things clear) that the commit ID (which comes after the "`--hard`" parameter) should be the ID of whatever commit you want to reset your branch to. – Michael Dautermann Jul 27 '12 at 20:20
  • how come when I do `git pull`, I get something like: `fe88549..50a8083 master -> origin/master Already up-to-date.` – Jürgen Paul Jul 26 '13 at 02:07
  • 1
    Rewrote history nicely... anyone who could have pulled the changes, I just made sure they did a `git reset --hard [commit_id]` so we didn't mess with the space-time continuum. – Alien Life Form Sep 14 '15 at 22:36
  • 11
    What is the + for in "git push origin +alpha-0.3.0"? – jpierson Mar 31 '17 at 17:55
  • Hi, I do only `git push -f origin 99157a1b1b27820dfba48c5e9d3c4f075670670c:master ` as Charles recipe, and **nothing ocurr**... How to use your recipe? It is the *simplest case*: delete the last commit from master. – Peter Krauss Feb 16 '18 at 13:39
  • This rewrites history and I believe you'll need to force your push in this case. eg(git push -f .....) – RayLoveless Jul 18 '18 at 16:47
  • 3
    @jpierson `+` forces the push to take place, similarly to `-f` (but slightly different: https://stackoverflow.com/a/25937833/1757149). Without it, if you try `git push origin alpha-0.3.0` the push will fail: `Updates were rejected because the tip of your current branch is behind`. – A__ Nov 28 '18 at 15:37
132

git revert is less dangerous than some of the approaches suggested here:

prompt> git revert 35f6af6f77f116ef922e3d75bc80a4a466f92650
[master 71738a9] Revert "Issue #482 - Fixed bug."
 4 files changed, 30 insertions(+), 42 deletions(-)
prompt> git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
prompt>

Replace 35f6af6f77f116ef922e3d75bc80a4a466f92650 with your own commit.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
neoneye
  • 50,398
  • 25
  • 166
  • 151
  • 2
    How do I come up with the 35f6af6f77f116ef922e3d75bc80a4a466f92650 ID? This answer would be better if you could explain that. – Volomike Jun 12 '13 at 02:58
  • 4
    @Volomike (and Googling devs of the future), this question describes many ways of obtaining it: [version control and hash question on SO](http://stackoverflow.com/questions/949314/how-to-retrieve-the-hash-for-the-current-commit-in-git) – Jaime Oct 28 '13 at 17:32
  • This is the right answer, because with "git reset" you should not be able to push (Updates were rejected because the tip of your current branch is behind its remote counterpart) or you need to force the pull which is not really clean. – Thomas Decaux Aug 19 '14 at 10:54
  • This was working for me. However, be careful as revert will revert all changes in your local files. – user1941537 Mar 12 '19 at 10:14
  • I opted for this approach multiple times but also I use git rebase -i to do an interactive rebase and clean up history as suggested here, https://stackoverflow.com/questions/5189560/squash-my-last-x-commits-together-using-git. – Ernesto Allely Jun 17 '19 at 07:38
  • @Volomike just do git log and you will find it – Rick Il Grande May 04 '20 at 19:03
  • For beginners: [git revert](https://git-scm.com/docs/git-revert) only reverts the ONE commit you mention. It does NOT restore your commit back to exactly match the commit mentioned. Use `git restore` for that. – Josiah Yoder Jun 30 '21 at 21:03
55

A way to do it without losing the changes you wanted:

git reset cc4b63b 
git stash
git push -f origin alpha-0.3.0
git stash pop

Then you can choose the files you meant to push

curmil
  • 1,077
  • 13
  • 9
37
git push origin +7f6d03:master

This will revert your repo to mentioned commit number

ireshika piyumalie
  • 2,226
  • 22
  • 22
37

The accepted solution (from @charles bailey) is highly dangerous if you are working in a shared repo.

As a best practice, all commits pushed to a remote repo that is shared should be considered 'immutable'. Use 'git revert' instead: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#fixing-mistakes

https://git-scm.com/book/be/v2/Git-Basics-Undoing-Things

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
Saboosh
  • 409
  • 4
  • 7
  • 2
    What, exactly, are the instructions you are prescribing? You only seem to have old links. – jww Jan 26 '16 at 07:09
33
git reset --hard HEAD^
git push origin -f

This will remove the last commit from your local device as well as Github

Rakib Noushad
  • 339
  • 3
  • 3
  • 1
    Just to be clear, git reset --hard is a DANGEROUS command. Any previously pending changes to the Staging Index and the Working Directory gets reset to match the state of the Commit Tree. This means any pending work that was hanging out in the Staging Index and Working Directory will be lost. – nico_lrx Apr 20 '23 at 12:11
25

Another way to do this:

  1. create another branch
  2. checkout the previous commit on that branch using "git checkout"
  3. push the new branch.
  4. delete the old branch & push the delete (use git push origin --delete <branch_name>)
  5. rename the new branch into the old branch
  6. push again.
Bryan Dimas
  • 1,389
  • 13
  • 18
Rushabh Mehta
  • 1,463
  • 16
  • 15
18

Scenario 1: If you want to undo the last commit say 8123b7e04b3, below is the command(this worked for me):

git push origin +8123b7e04b3^:<branch_name>

Output looks like below:

Total 0 (delta 0), reused 0 (delta 0)
To https://testlocation/code.git
 + 8123b7e...92bc500 8123b7e04b3^ -> master (forced update)

Note: To update the change to your local code (to remove the commit locally as well) :

$ git reset --hard origin/<branchName>
Message displayed is :    HEAD is now at 8a3902a comments_entered_for_commit

Additional info: Scenario 2: In some situation, you may want to revert back what you just undo'ed (basically undo the undo) through the previous command, then use the below command:

git reset --hard 8123b7e04b3
git push

Output:

HEAD is now at cc6206c Comment_that_was_entered_for_commit

More info here: https://github.com/blog/2019-how-to-undo-almost-anything-with-git

Barani r
  • 2,119
  • 1
  • 25
  • 24
  • 1
    Scenario 1 should the accepted answer since the question did not specify which commit to delete. The accepted answer only deletes the *last* commit. This answer deletes *any* commit. – Dominic Cerisano Oct 07 '19 at 20:46
17

Undo multiple commits git reset --hard 0ad5a7a6 (Just provide commit SHA1 hash)

Undo last commit

git reset --hard HEAD~1 (changes to last commit will be removed ) git reset --soft HEAD~1 (changes to last commit will be available as uncommited local modifications)

DINA TAKLIT
  • 7,074
  • 10
  • 69
  • 74
JayminLimbachiya
  • 971
  • 1
  • 13
  • 19
7

you can use the command reset

git reset --soft HEAD^1

then:

git reset <files>
git commit --amend

and

git push -f
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
0

The existing answers are good and correct, however what if you need to undo the push but:

  1. You want to keep the commits locally or you want to keep uncommitted changes
  2. You don't know how many commits you just pushed

Use this command to revert the change to the ref:

git push -f origin refs/remotes/origin/<branch>@{1}:<branch>
Vlad274
  • 6,514
  • 2
  • 32
  • 44
0

To revert the push

git reset --hard HEAD@{1}
git push -f
git reset --hard HEAD@{1}

now your local will be ahead to remote

git reset --hard origin/master

or alternative way

  1. To reset the push: git reset --soft HEAD^1

  2. Will appear modify file so reset them: git reset <files>

  3. git commit --amend

  4. git push -f

rnewed_user
  • 1,386
  • 7
  • 13
0

I had the same issue. I just copy the last commit id(af12de...) which I wanted to revert. Then executes this command git revert af12de.... Then push my changes to the master. This worked for me

chety
  • 136
  • 4
0

If you want to undo a certain push, you can also do this interactively via

git rebase -i HEAD~n

where n should denote how many commits into the past you want to go, e.g.

git rebase -i HEAD~5

Now you can interactively go to the commit in the terminal you want to drop (remove) and write "drop" (though in the terminal that opens up, this is also explained very well).

When you are done with the rebase, do not forget to forcably push the changes, i.e.

git push origin branch_name --force
Hermi
  • 350
  • 2
  • 5
  • 16
-2

If you want to ignore the last commit that you have just pushed in the remote branch: this will not remove the commit but just ignoring it by moving the git pointer to the commit one earlier, refered by HEAD^ or HEAD^1

git push origin +HEAD^:branch

But if you have already pushed this commit, and others have pulled the branch. In this case, rewriting your branch's history is undesirable and you should instead revert this commit:

git revert <SHA-1>
git push origin branch
qingy2019
  • 536
  • 7
  • 23
mkebri
  • 2,025
  • 1
  • 16
  • 14
  • The question is about "push" then it concern the Remote branch. No to move the HEAD about one commit which mean ignore the last commit pushed just do this: git push origin +HEAD^:your_branch – mkebri Apr 20 '18 at 15:43