grautur
grautur

Reputation: 30505

Revert some Git commits, keep others?

Suppose I make commits A, B, and C, all of which touched entirely different codepaths. (So they're independent and commit B can exist without the changes in A, and so on.)

Commit A introduced a bug, while commits B and C are fine. So I want to revert to the state of my code before commit A, and then commit changes B and C.

What's the best way to do this? One way is to simply do a git revert <SHA-of-commit-before-A> and then manually add back in commits B and C -- is there a better solution?

Upvotes: 4

Views: 97

Answers (2)

VonC
VonC

Reputation: 1328602

You don't need to add back B and C: they are already committed and won't be impacted by your revert which add a new commits (negative image of A).

Another way is (if you don't have already pushed those commits) to do an interactive rebase (git rebase -i A^), and reorder your commits, dropping A completely.
You will see in your rebase the following options (see git Book)

# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

But again, that will change your history and will make you a git push --force, which isn't always a good idea, if other people already have pulled from your repo.
In that case, the revert remains the safest solution.

Upvotes: 4

Ben Jackson
Ben Jackson

Reputation: 93890

If you've already pushed your changes (so they are visible to others) the right thing to do is git-revert <SHA-of-A>. That explicitly makes a new commit that's the opposite of A. If no one has seen your tree yet you can use git-rebase -i A^ (where A^ means "parent of A") to interactively reorder or omit commits since A. In this case you could remove A and it would do exactly what you described (unwind to just before A and then reapply only B and C).

Upvotes: 3

Related Questions