What I do in these cases is:
In the server, move the cursor back to the last known good commit:
git push -f origin <last_known_good_commit>:<branch_name>
Locally, do the same:
git reset --hard <last_known_good_commit>
# ^^^^^^
# optional
See a full example on a branch my_new_branch
that I created for this purpose:
$ git branch
my_new_branch
This is the recent history after adding some stuff to myfile.py
:
$ git log
commit 80143bcaaca77963a47c211a9cbe664d5448d546
Author: me
Date: Wed Mar 23 12:48:03 2016 +0100
Adding new stuff in myfile.py
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date: Tue Mar 18 12:46:59 2016 +0100
Initial commit
I want to get rid of the last commit, which was already pushed, so I run:
$ git push -f origin b4zad078237fa48746a4feb6517fa409f6bf238e:my_new_branch
Total 0 (delta 0), reused 0 (delta 0)
To [email protected]:me/myrepo.git
+ 80143bc...b4zad07 b4zad078237fa48746a4feb6517fa409f6bf238e -> my_new_branch (forced update)
Nice! Now I see the file that was changed on that commit (myfile.py
) shows in "not staged for commit":
$ git status
On branch my_new_branch
Your branch is up-to-date with 'origin/my_new_branch'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: myfile.py
no changes added to commit (use "git add" and/or "git commit -a")
Since I don't want these changes, I just move the cursor back locally as well:
$ git reset --hard b4zad078237fa48746a4feb6517fa409f6bf238e
HEAD is now at b4zad07 Initial commit
So now HEAD is in the previous commit, both in local and remote:
$ git log
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date: Tue Mar 18 12:46:59 2016 +0100
Initial commit