2

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 ?

sergiuz
  • 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 Answers3

5

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.

Igal S.
  • 13,146
  • 5
  • 30
  • 48
  • Tx Igal, Can you elaborate your answer a bit? – sergiuz Oct 13 '15 at 14:14
  • Done. Edited my answer. – Igal S. Oct 13 '15 at 14:23
  • 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
2

try git revert C

...and best also read man git-revert

Stephan W.
  • 188
  • 13
2

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.

mariux
  • 2,807
  • 12
  • 21
  • 1
    So 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