There are four ways of doing so:

  • Clean way, reverting but keep in log the revert:

    git revert --strategy resolve <commit>
    
  • Harsh way, remove altogether only the last commit:

    git reset --soft "HEAD^"
    

Note: Avoid git reset --hard as it will also discard all changes in files since the last commit. If --soft does not work, rather try --mixed or --keep.

  • Rebase (show the log of the last 5 commits and delete the lines you don't want, or reorder, or squash multiple commits in one, or do anything else you want, this is a very versatile tool):

    git rebase -i HEAD~5
    

And if a mistake is made:

git rebase --abort
  • Quick rebase: remove only a specific commit using its id:

    git rebase --onto commit-id^ commit-id
    
  • Alternatives: you could also try:

    git cherry-pick commit-id
    
  • Yet another alternative:

    git revert --no-commit
    
  • As a last resort, if you need full freedom of history editing (eg, because git don't allow you to edit what you want to), you can use this very fast open source application: reposurgeon.

Note: of course, all these changes are done locally, you should git push afterwards to apply the changes to the remote. And in case your repo doesn't want to remove the commit ("no fast-forward allowed", which happens when you want to remove a commit you already pushed), you can use git push -f to force push the changes.

Note2: if working on a branch and you need to force push, you should absolutely avoid git push --force because this may overwrite other branches (if you have made changes in them, even if your current checkout is on another branch). Prefer to always specify the remote branch when you force push: git push --force origin your_branch.


Here is an easy solution:

git rebase -i HEAD~x

(Note: x is the number of commits)

upon executing notepad file will open. Enter drop besides your commit.
If you don’t know Vim, just click on each word pick that you want to edit and then hit the "I" key (for insert mode). Once you’re done typing hit the "esc" key to exit insert mode.



enter image description here

and that's it, you are done... Just sync the git dashboard and the changes will be pushed to remote.

If the commit you drop was already on the remote, you will have to force push. Since --force is considered harmful, use git push --force-with-lease.


The algorithm that Git uses when calculating diffs to be reverted requires that

  1. The lines being reverted are not modified by any later commits.
  2. There not be any other "adjacent" commits later in history.

The definition of "adjacent" is based on the default number of lines from a context diff, which is 3. So if 'myfile' was constructed like this:

$ cat >myfile <<EOF
line 1
junk
junk
junk
junk
line 2
junk
junk
junk
junk
line 3
EOF
$ git add myfile
$ git commit -m "initial check-in"
 1 files changed, 11 insertions(+), 0 deletions(-)
 create mode 100644 myfile
$ perl -p -i -e 's/line 2/this is the second line/;' myfile
$ git commit -am "changed line 2 to second line"
[master d6cbb19] changed line 2
 1 files changed, 1 insertions(+), 1 deletions(-)
$ perl -p -i -e 's/line 3/this is the third line/;' myfile
$ git commit -am "changed line 3 to third line"
[master dd054fe] changed line 3
 1 files changed, 1 insertions(+), 1 deletions(-)
$ git revert d6cbb19
Finished one revert.
[master 2db5c47] Revert "changed line 2"
 1 files changed, 1 insertions(+), 1 deletions(-)

Then it all works as expected.

The second answer was very interesting. There is a feature that has not yet been officially released (though it is available in Git v1.7.2-rc2) called Revert Strategy. You can invoke git like this:

git revert --strategy resolve <commit>

and it should do a better job of figuring out what you meant. I do not know what the list of available strategies is, nor do I know the definition of any strategy.


Your choice is between

  1. keeping the error and introducing a fix and
  2. removing the error and changing the history.

You should choose (1) if the erroneous change has been picked up by anybody else and (2) if the error is limited to a private un-pushed branch.

Git revert is an automated tool to do (1), it creates a new commit undoing some previous commit. You'll see the error and removal in the project history but people who pull from your repository won't run into problems when they update. It's not working in an automated manner in your example so you need to edit 'myfile' (to remove line 2), do git add myfile and git commit to deal with the conflict. You will then end up with four commits in your history, with commit 4 reverting commit 2.

If nobody cares that your history changes, you can rewrite it and remove commit 2 (choice 2). The easy way to do this is to use git rebase -i 8230fa3. This will drop you into an editor and you can choose not to include the erroneous commit by removing the commit (and keeping "pick" next to the other commit messages. Do read up on the consequences of doing this.


Approach 1

First get the commit hash(ex:1406cd61) that you need to revert. simple fix will be below command,

$ git revert 1406cd61

if you have commit more changes related to 1406cd61 files after 1406cd61 commit, Above simple command will not work. Then you have to do the below steps, which is cherry picking.

Approach 2

Please follow below sequence of actions, Since we are using --force you need to have admin rights over the git repo to do this.

Step 1: Find the commit before the commit you want to remove git log

Step 2: Checkout that commit git checkout <commit hash>

Step 3: Make a new branch using your current checkout commit git checkout -b <new branch>

Step 4: Now you need to add the commit after the removed commit git cherry-pick <commit hash>

Step 5: Now repeat Step 4 for all other commits you want to keep.

Step 6: Once all commits have been added to your new branch and have been committed. Check that everything is in the correct state and working as intended. Double check everything has been committed: git status

Step 7: Switch to your broken branch git checkout <broken branch>

Step 8: Now perform a hard reset on the broken branch to the commit prior to the one your want to remove git reset --hard <commit hash>

Step 9: Merge your fixed branch into this branch git merge <branch name>

Step 10: Push the merged changes back to origin. WARNING: This will overwrite the remote repo! git push --force origin <branch name>

You can do the process without creating a new branch by replacing Step 2 & 3 with Step 8 then not carry out Step 7 & 9.