How do I delete a bad commit, while keeping later commits?

Go To


Let's say I have these commits in chronological order:

  1. a
  2. b
  3. c

Now, I want to get rid of b but keep c, so that I have:

  1. a
  2. c

How do I do this?

(there are no conflicts between b and c)

2012-04-03 20:16
by Matt Fenwick
Have you pushed any of these to a remote - Nic 2012-04-03 20:18


In case you already pushed the changes to a remote, you could use:

$ git revert <hash of commit b>

that creates a new commit d that removes the changes of commit b

2012-04-03 20:41
by stewe
Cool! And does it preserve commit c - Matt Fenwick 2012-04-03 20:42
Yes it does, : - stewe 2012-04-03 20:46
Literally what it's doing is creating a new commit that's the inverse of b, and committing it on top of c. It should roll out anything that came in on commit b, and leave a trail of the mistake and cleanup in history, which some people don't like, but I really do - Dan Ray 2012-04-03 20:48


Assuming you haven't already pushed to a remote repository, you can do an interactive rebase. See here:

2012-04-03 20:19
by Stuart Golodetz


If you only need the one commit from the HEAD, you can use cherry-pick on a different branch to bring just that commit over:

$ git checkout -b working
$ git reset --hard <hash of the commit `a`>
$ git cherry-pick <hash of the commit `c`>

The hard reset changes the working copy back to the state as of that commit, and then the cherry-pick applies the changes introduced in commit c directly on top of your working copy.

2012-04-03 20:22
by Alex Vidal


The help for git rebase talks about this exact case! Check it out:

A range of commits could also be removed with rebase. If we have the
   following situation:

           E---F---G---H---I---J  topicA

   then the command

       git rebase --onto topicA~5 topicA~3 topicA

   would result in the removal of commits F and G:

           E---H'---I'---J'  topicA

   This is useful if F and G were flawed in some way, or should not be
   part of topicA. Note that the argument to --onto and the <upstream>
   parameter can be any valid commit-ish.
2012-04-03 20:47
by GoZoner
Is topicA the branch name - Matt Fenwick 2012-04-03 20:51
Yes. In the example, topicA~5 could be any commit; it would be 'c' in your question. topicA~3 would be 'a - GoZoner 2012-04-03 20:58