Suppose I have a list of commits:
A > B > C > D > E
, how can I remove from history the changes made in C , to have A > B > D > E
?

- 5,353
- 1
- 35
- 51
-
You need to clarify whether or not you want to keep C in your history or not, or if you merely want to undo its changes in your current version of the code base, and you don't care if C is still in your history. Does it even matter to you? – Oct 13 '15 at 14:24
-
See also [Undo a particular commit in Git](http://stackoverflow.com/q/2318777/456814). – Oct 13 '15 at 14:30
-
In this case, I do not care about C commit, I drop it. – sergiuz Oct 13 '15 at 14:31
3 Answers
You can always revert the changes.
git revert C
If you want to rewrite history, this is what rebase
is for. You need to:
git rebase -i A
Then remove C from the list of the commits.
Longer explanation:
First option reverts the change by creating a new commit which is the opposite of the original commit. So the repository would look like:
A > B > C > D > E > C`
Where C` is opposite of C. Basically, same as patch --reverse
Second option changes the history. rebase
allows you to select specific commits, change order of commits, and much more. I suggest reading git-rebase.
The -i
flag is for interactive mode which let the user edit the list of commits before rebasing.
If you remove C from the list of commits and perform the rebase, the actual output would be
A > B > D > E
You have no longer history of C in the branch.
Note: In both cases you may have conflicts in the process. In first case because you are applying C` over E, and in the second case because you applying D over B.

- 13,146
- 5
- 30
- 48
-
-
-
You should mention that rebase shouldn't be used if other people also have commit C in their history. Or if those people are okay with having to also rebase/redo their work on top of the rewritten commit, then rebase is ok, but you don't just rebase shared history lightly, in any case. – Oct 13 '15 at 14:28
You can't do it and get A > B > D > E
.
You will always end up with A > B > D' > E'
To remove the changes introduced in C you can use
git rebase --onto <newbase> <oldbase> <commit/branch>
in your case:
git rebase --onto B C E
This will place changes introduced in D..E
from the old base C
onto the new base B
(if you do not hit any conflicts) resulting in
A > B > D' > E'
It is important to note that D
and E
get new sha IDs resulting in D'
and E'
so if you already published C
, D
or E
use the revert approach (git revert C
) or you might mess up other peoples history.

- 2,807
- 12
- 21
-
1So this answer is a little misleading. While it is true that D and E are rewritten to have new sha IDs, the *changes* introduced by each commit are still the same. – Oct 13 '15 at 14:39
-
hi.. thanks, tried to reword my answer to reflect that it is still possible to remove changes made in `C` but not end up with the same sha ID for `E` – mariux Oct 13 '15 at 14:45