tags:

views:

2974

answers:

5

Suppose you git history looks like this:

1 2 3 4 5

Where 1-5 are separate revisions. You need to remove 3 while still keeping 1, 2, 4 and 5. How to do it?

Is there an efficient method when there are hundreds of revisions after the one to be deleted?

+3  A: 

Do you want to remove the changes that come with the revision, or do you just want to remove any evidence that a revision was made at that point?

Also, take a look at the git documentation.

+9  A: 

To combine revision 3 and 4 into a single revision, you can use git rebase. If you want to remove the changes in revision 3, you need to use the edit command in the interactive rebase mode. If you want to combine the changes into a single revision, use squash.

I have successfully used this squash technique, but have never needed to remove a revision before. The git-rebase documentation under "Splitting commits" should hopefully give you enough of an idea to figure it out. (Or someone else might know).

From the git documentation:

Start it with the last commit you want to retain as-is:

git rebase -i <after-this-commit>

An editor will be fired up with all the commits in your current branch (ignoring merge commits), which come after the given commit. You can reorder the commits in this list to your heart's content, and you can remove them. The list looks more or less like this:

pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...

The oneline descriptions are purely for your pleasure; git-rebase will not look at them but at the commit names ("deadbee" and "fa1afe1" in this example), so do not delete or edit the names.

By replacing the command "pick" with the command "edit", you can tell git-rebase to stop after applying that commit, so that you can edit the files and/or the commit message, amend the commit, and continue rebasing.

If you want to fold two or more commits into one, replace the command "pick" with "squash" for the second and subsequent commit. If the commits had different authors, it will attribute the squashed commit to the author of the first commit.

garethm
+6  A: 

If all you want to do is remove the changes made in revision 3, you might want to use git revert.

Git revert simply creates a new revision with changes that undo all of the changes in the revision you are reverting.

What this means, is that you retain information about both the unwanted commit, and the commit that removes those changes.

This is probably a lot more friendly if it's at all possible the someone has pulled from your repository in the mean time, since the revert is basically just a standard commit.

SpoonMeiser
+1  A: 

Here is a way to remove non-interactively a specific commit id knowing only the commit id you would like to remove.

git rebase --onto commit-id^ commit-id HEAD

rado