Remove specific commit Remove specific commit git git

Remove specific commit


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 <<EOFline 1junkjunkjunkjunkline 2junkjunkjunkjunkline 3EOF$ 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 d6cbb19Finished 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.