I have a project in a remote repository, synchronized with a local repository (development) and the server one (prod). I've been making some commited changes already pushed to remote and pulled from the server. Now, I want to undo those changes. So I could just git checkout to the commit before the changes and commit the new changes, but I'm guessing that there will be problems to push them again to remote. Any suggestion on how should I proceed?

0

14 Answers

You can revert individual commits with:

git revert <commit_hash> 

This will create a new commit which reverts the changes of the commit you specified. Note that it only reverts that specific commit, and not commits that come after that. If you want to revert a range of commits, you can do it like this:

git revert <oldest_commit_hash>..<latest_commit_hash> 

It reverts all the commits after <oldest_commit_hash> up to and including <latest_commit_hash>. On some versions of git it also reverts the <oldest_commit_hash>, so double check if that commit gets reverted or not. You can always drop the latest revert commit (which reverts the oldest commit) with g reset --hard HEAD~.

To know the hash of the commit(s) you can use git log.

Look at the git-revert man page for more information about the git revert command. Also, look at this answer for more information about reverting commits.

14

A solution that keeps no traces of the "undo".

NOTE: don't do this if someone already pulled your change (I would use this only on my personal repo.)

run:

git reset <previous label or sha1> 

this will re-checkout all the updates locally (so git status will list all updated files)

then you "do your work" and re-commit your changes (Note: this step is optional)

git commit -am "blabla" 

At this moment your local tree differs from the remote

git push -f <remote-name> <branch-name> 

will force the remote branch to take this push and remove the previous one (specifying remote-name and branch-name is not mandatory but is recommended to avoid updating all branches with update flag).

!! watch-out some tags may still be pointing removed commit !! how-to-delete-a-remote-tag

17

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 :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 
12

This will remove your pushed commits

git reset --hard 'xxxxx' git clean -f -d git push -f 
14

You can REVERT (or you can also call it DELETE) the Git Commit BOTH Locally and Remotely if you follow the steps as given below via git command line.

Run the following command to see the commit id that you want to revert

git log --oneline --decorate --graph 

You will get like a following screenshot enter image description here

If you also check remote (via Web Interface) then you can see that this would be same as shown below

enter image description here

As per screenshot currently you are on commit id e110322 however you want to revert back to 030bbf6 BOTH LOCALLY and REMOTELY.

Perform the following steps to DELETE/REVERT Commits Locally+Remotely


First Locally Reverting to commit id 030bbf6

git reset --hard 030bbf6 

followed by

git clean -f -d 

These two commands clean force reset to commit stage 030bbf6 as shown below in snapshot

enter image description here

now if you run git status then you'll see that you are TWO Commits BEHIND from the remote branch as shown below enter image description here

Run following to update your indexes (if there are any updates). It is recommended that you ask all developers not to accept any pull requests on main remote branch.

git fetch --all 

Once you are done with it then you are required to Push this commit forcefully by using + symbol in-front of branch as shown below. I have used here as master branch, you can replace it with any

enter image description here Code

git push -u origin +master 

now if you see the web interface of remote then commit there should be reverted as well.

enter image description here

6

Let's say 61234 is the sha-number of the last good commit you want to keep.

git reset --hard 61234 git push -f 


 will remove completely all wrong commits without any trace.

Note: If you wanted to push (the commit you reset to) to a specific branch you'd use git push -f origin branch-name instead.

5

2020 Simple way :

git reset <commit_hash> 

(The hash of the last commit you want to keep).

You will keep the now uncommitted changes locally.

If you want to push again, you have to do :

git push -f 
2
git revert HEAD -m 1 

In the above code line. "Last argument represents"

  • 1 - reverts one commits.

  • 2 - reverts last two commits.

  • n - reverts last n commits.

You need to push after this command to take the effect on remote. You have other options like specifying the range of commits to revert. This is one of the option.


Later use git commit -am "COMMIT_MESSAGE" then git push or git push -f

2

The reset hard worked for me: Thanks @Mo D Genensis and @vibs2006

 git reset --hard 'your last working commit hash' git clean -f -d git push -f 
2

Here is my way:

Let's say the branch name is develop.

# Checkout a new temp branch based on one history commit(cmd to get history: git log) git checkout <last_known_good_commit_hash> # Delete the original develop branch git branch -D develop # Create a new develop branch based on the temp branch git checkout -b develop # Force update this new branch git push -f origin develop 
2

To do it cleanly:

git rebase -i <hash of last good commit, 9 chars is enough> 

Now you will get a list of the commits from the last good commit to the HEAD with options what to do with each commit. DROP will throw away that commit. Save the file.

Now to fix the upstream do :

git push --force-with-lease 

(With lease so you don't accidentally cause problems for someone else working on your pushed update)

This keeps the log clean by removing the wrong commit instead of introducing new commits fixing earlier erroneous commits.

2

You can do something like

git push origin +<short_commit_sha>^:<branch_name> 
1

git reset <commit_hash> (to get the<commit_hash> use git log --oneline)

git restore . to restore all the changed files to the version of yout target commit

git push origin master --force to force the push to your remote master branch. But be careful when using the force push if there is anyone working with you in the same branch

Another way to do this without revert (traces of undo):

Don't do it if someone else has pushed other commits

Create a backup of your branch, being in your branch my-branch. So in case something goes wrong, you can restart the process without losing any work done.

git checkout -b my-branch-temp 

Go back to your branch.

git checkout my-branch 

Reset, to discard your last commit (to undo it):

git reset --hard HEAD^ 

Remove the branch on remote (ex. origin remote).

git push origin :my-branch 

Repush your branch (without the unwanted commit) to the remote.

git push origin my-branch 

Done!

I hope that helps! ;)